diff --git a/.gitmodules b/.gitmodules index a52486fc..f4da1a09 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,9 @@ [submodule "make-novice"] path = make-novice url = https://github.com/swcarpentry/make-novice.git +[submodule "python-ecology-lesson"] + url = https://github.com/carpentries-i18n/python-ecology-lesson.git + path = python-ecology-lesson +[submodule "instructor-training"] + path = instructor-training + url = git@github.com:carpentries-i18n/instructor-training.git diff --git a/README.md b/README.md index 7135437a..554253d1 100644 --- a/README.md +++ b/README.md @@ -139,3 +139,107 @@ POファイルを編集したあと、翻訳された Markdown ファイルを [メンテナーと管理者のガイド](docs/admin.md) を見てください ご協力いただきありがとうございます。たとえ小さな貢献であっても、大歓迎です。 + +# Internationalisation of carpentry lessons + +## How does this work? + +1. Add a submodule for the lessons that you want to translate +1. Run `po4gitbook/update.sh` - That creates/updates the `po` directory with the `.pot` files to use in translations. +1. Create a `po` file and start translating! + - copy `.pot` to `..po`. e.g., + ```bash + cd po + cp shell-novice.pot shell-novice.es.po + ``` + - Edit the file with your favourite po editor ([PoEdit](http://www.poedit.net), + [GTranslator](https://wiki.gnome.org/Apps/Gtranslator), [Lokalize](https://userbase.kde.org/Lokalize), ...) + Note: + - "`Language`" field is needed to add to the header (at least with gtranslator), the rest is put by the tool. + - "`Language-Team:`" needs the first letter in upper case (e.g., `Es`) + - Create `po/LINGUAS` + - run `po4gitbook/compile.sh` - This creates a `locale//` tree directory + + +## Using Transifex + +[Transifex]() is a collaborative platform for translations. We can upload the +`pot` files produced by the `update` command. However, to have a better user +experience on that platform we suggest that the `lesson_file.pot` is broken into +one per chapter. To do so you can use the helper script available in this repository + +```bash +$ lesson="TheSuperLesson" +$ python helpers/splitpot.py po/${lesson}.pot +``` + +This, by default, will break `TheSuperLesson.pot` file and create a +`TheSuperLesson` directory under `transifex` and fill it up with one file per +chapter. + +Now we will proceed to use the [transifex-client](https://docs.transifex.com/client/installing-the-client) +to push the split files. + +1. Browse to the directory of the lesson and create the `` directory that + you would like to get translating: + + ```bash + $ cd transifex/${lesson} + $ mkdir es + ``` + + We will proceed to generate the files to push to transifex. Read the [[appendix]] + below for more information to do it manually. + +1. Run the transifex command to generate all the files needed. + + ```bash + tx config mapping-bulk -p ${lesson} --source-language en --type PO -f '.pot' \ + --source-file-dir pot --expression "/{filename}.po" --execute + ``` + + Note that you need to create that project (lesson) manually in + [transifex](https://www.transifex.com/carpentries-i18n/add/) + +1. Next we proceed to push the sources to the website + + ```bash + tx push -s --parallel + ``` + + This can take a while... + +1. Advertise between the translators, give access to people through the portal + +1. translate, translate, translate + +1. when you want to download a particular translation for building the lesson + you need to, pull and combine: + + ```bash + $ language="es" + $ cd transifex/${lesson} + $ tx pull -t ${language} # This should download the `po` files in transifex/${lesson}/${language} + $ # Then proceed to join the files into a single one + $ cd .. + $ python helpers/splitpot.py po/${lesson}.pot --join transifex/${lesson} --lang ${language} + $ # Compile the repository with po4gitbook so it creates the locale for the lesson + $ po4gitbook/compile.sh # This creates a `locale//` tree directory + ``` + +# Appendix + +## Transifex manual process + +1. initialise the transifex project (if this is your first time then you may + [set up your + token](https://docs.transifex.com/client/init#first-tx-init-run)). + + ```bash + $ tx init + ``` + + Answer the questions that follows as required. **Note** if the script hangs a + the path expression step, is because it doesn't find the `` directory. + Make sure to create one first (*e.g.,* `mkdir es`) + diff --git a/helpers/lesson2theme.py b/helpers/lesson2theme.py new file mode 100644 index 00000000..016fb2b5 --- /dev/null +++ b/helpers/lesson2theme.py @@ -0,0 +1,196 @@ +from argparse import ArgumentParser +import glob +import os +from pathlib import Path +import shutil +import tempfile + +from git import Repo +from github import Github +from ruamel.yaml import YAML + + +def clone_repo_as_submodule(org, project, tmpdir='/tmp'): + ''' + org: swcarpentry + project: git-novice + ''' + + tmpdir = Path(tmpdir) + if os.environ['gh_access_token']: + g = Github(os.environ['gh_access_token']) + else: + # ask for user name and password + # g = Github(username, password) + raise NotImplementedError + github_user = g.get_user() + + # from carpentries URL git repo to new Repo in swc-i18n + repo = g.get_repo(f'{org}/{project}') + # Fork repository + carp_18n_org = [n for n in github_user.get_orgs() if "i18n" in n.login][0] + # it doesn't create it if it exists. + carp_i18n_fork = carp_18n_org.create_fork(repo) + carp_i18n_fork.edit(homepage=f"https://carpentries-i18n.github.io/{project}/") + + i18n_local = Repo(".") # FIXME How should I pass the directory? + + + sm_exists = any(filter(lambda x: f"{project}" in x.name, i18n_local.submodules)) + + if sm_exists: + return i18n_local, Repo(f"{project}"), carp_i18n_fork, github_user + + # Creates a new branch for keep this lesson changes + project_branch = i18n_local.create_head(project) + i18n_local.head.reference = project_branch + project_sm = i18n_local.create_submodule(project, project, url=carp_i18n_fork.clone_url) + project_sm.update() + # Clone repository + i18n_local.index.commit(f"Adds {project} submodule.") + return i18n_local, Repo(f"{project}"), repo, carp_i18n_fork, project_sm, github_user + + +def clean_wrong_format(directory): + + files = glob.glob(f"{directory}/**/*md") + changes = 0 + for f in files: + with open(f, 'r') as mdfile: + all_lines = mdfile.readlines() + bad_lines = [] + for i, line in enumerate(all_lines): + if "{:" in line: + # This is to cover whether the line starts with {: or with > {: + if set(all_lines[i-1].split()) == set('>'): + bad_lines.append(i-1) + if bad_lines: + changes += 1 + bad_lines.reverse() + with open(f, 'w') as mdfile: + for bad_line in bad_lines: + all_lines.pop(bad_line) + mdfile.writelines(all_lines) + + return changes + + +def themetise_lesson(clone): + + branch_ghpages = clone.create_head("gh_pages_theme") + clone.head.reference = branch_ghpages + + # Clean repository + # what's provided by theme + dir_remove = ['_layouts', '_includes', '_episodes_rmd', 'assets', 'bin', 'code', 'css'] #, 'files'] + for entry in os.listdir(clone.working_dir): + if entry in dir_remove and os.path.isdir(os.path.join(clone.working_dir, entry)): + shutil.rmtree(os.path.join(clone.working_dir, entry)) + + # add theme to `_config.yml` + yaml = YAML() + with open(clone.working_dir + '/_config.yml') as mm: + config = yaml.load(mm) + + config.insert(1, 'remote_theme', "carpentries-i18n/carp-theme", comment="Theme URL") + + elem_remove = ['amy_site', 'carpentries_github', 'carpentries_pages', 'carpentries_site', + 'dc_site', 'example_repo', 'example_site', 'lc_site', 'swc_github', + 'swc_pages', 'swc_site', 'template_repo', 'training_site', + 'workshop_repo', 'workshop_site', 'pre_survey', 'post_survey', + 'training_post_survey'] + for elem in elem_remove: + if elem in config: + config.pop(elem) + + with open(clone.working_dir + '/_config.yml', 'w') as mm: + yaml.dump(config, mm) + + + clone.git.add(update=True) + clone.index.commit('Removed all files that are provisioned by theme.') + + # Add locale bits to config + with open(clone.working_dir + '/_config.yml') as mm: + config = yaml.load(mm) + + config['collections']['locale'] = {'output': True, + 'permalink': '/:path/index.html'} + config['defaults'].append({'scope': {'path': "", 'type': "locale"}, + 'values': {'root': "..", 'layout': "episode"}}) + with open(clone.working_dir + '/_config.yml', 'w') as mm: + yaml.dump(config, mm) + + with open(clone.working_dir + "/aio.md", "r") as f: + contents = f.readlines() + + to_add = ['layout: page\n', 'permalink: /aio/\n'] + for i, line in enumerate(to_add): + if line not in contents: + contents.insert(i+1, line) + contents = "".join(contents) + + with open(clone.working_dir + "/aio.md", "w") as f: + f.write(contents) + + clone.git.add(update=True) + clone.index.commit('add bits to _config.yml to allow translations.') + + +def main(project): + + org, project = project.split('/') + parent, clone, upstream, fork, submod, github_user = clone_repo_as_submodule(org, project) + # add new remote with token so we can push + new_url = fork.html_url.replace('://', + f"://{github_user.login}:{os.environ['gh_access_token']}@") + clone.create_remote("topush", url=new_url) + + changes = clean_wrong_format(clone.working_dir) + if changes: + branch_format = clone.create_head("update_format") + clone.head.reference = branch_format + clone.git.add(update=True) + clone.index.commit(f"[translations] Fixed format that affects translations on {changes} file(s).") + clone.git.push("topush", "update_format") + # Create PR + # NOTE - this only seem to work on repositories where I have permission. + upstream.create_pull("[translations] Clean lessons to create po files", + "The `po` files are the tokenised version of the lessons. The [tool we are using](https://github.com/carpentries-i18n/po4gitbook) complains if the following *typos* or empty lines at the end of sections are not fixed.", + 'gh-pages', + 'carpentries-i18n:update_format', + True) + + #TODO Test if builds cleanly. + themetise_lesson(clone) + + # push repository + clone.git.push("topush", "gh_pages_theme:gh-pages") + print(f"Check {fork.html_url}/settings to see whether page is building OK") + + submod.binsha = submod.module().head.commit.binsha + parent.index.add([submod]) + parent.index.commit(f"Updates {project} to include theme.") + parent.git.push("origin", f"{project}") + + # TODO: + # - Create PR with the formatting changes + +if __name__ == "__main__": + parser = ArgumentParser(description="Cleanup of repository according translation template") + parser.add_argument('project', help='org/repo that you want to fork and theme from the carpentries') + arguments = parser.parse_args() + + main(arguments.project) + + project = arguments.project.split('/')[1] + print("If successful, run the following:") + print(f"1. Generate the po with po4gitbook/update.sh") + print(f"2. Break the file into chunks with python helpers/splitpot.py po/{project}.pot") + print(f"3. Create a language directory on the transifex lesson directory: e.g., mkdir -p transifex/{project}/es") + print(f"4. Build the transifex lesson: ") + print(f" - cd transifex/{project}") + print(f" - tx config mapping-bulk -p {project} --source-language en --type PO -f '.pot' \ ") + print(" --source-file-dir pot --expression \"/{filename}.po\" --execute ") + print(f"5. Create the project {project} in transifex: https://www.transifex.com/carpentries-i18n/add/") + print(f"6. Push the project to transifex: tx push -s --parallel") diff --git a/helpers/splitpot.py b/helpers/splitpot.py new file mode 100644 index 00000000..2d7b123a --- /dev/null +++ b/helpers/splitpot.py @@ -0,0 +1,172 @@ +from argparse import ArgumentParser +import configparser +import datetime +import glob +from pathlib import Path + +# from txclib.commands import _set_source_file + +# Input the lesson file that we want to split: splitplot.py lessonX.pot + +# Create directory with the file name: lessonX.pot => lessonX/ + +# Save header in memory; read till first empty line + +# Read first line, pattern: -> extract filename function +# #: lessonX/filename.md:YY +# if '#:' in line[:2] +# read till `:` => line[:2] +# Add to the filename with a number, for later join them properly together. -> save as 01_[folder-name_]file.pot +# Keep searching for whitespaces, look next line, same filename? add to it. + +def extract_filename(line): + ''' + provides the filename of a file from the po sections, like: + + "#: /path/to/file/with/courious.name:55" + + parameters + ---------- + line: a string containing a line with a filename. + + returns + ------- + filename: the name of the file. + ''' + if '#:' not in line[:2]: + raise TypeError("The current line is not one that contains a filename.") + line_bits = line.split(':') + filename = line_bits[1].strip().split('/')[-1] + return filename + + + +class Pofiles: + def __init__(self, filename): + self.filename = self._check_filename(filename) + self.lesson = self.filename.split('/')[-1].split('.')[0] + + def _check_filename(self, filename): + # filename is a pot/po file? + if '.po' not in filename[-4:]: + raise TypeError(f"The file {filename} doesn't has the right extension (.pot/.po)") + try: + with open(filename, 'r') as file_handler: + self.pot_content = file_handler.readlines() + # TODO Check file follows the pot format standard + except: + raise TypeError("There's been some error reading the file") + return filename + + def split(self, directory='transifex'): + # Check the given directory exists, if not create it: + split_directory = Path(directory) + if not split_directory.is_dir(): + split_directory.mkdir(parents=True) + # Create a directory for this lessons + lesson_directory = split_directory / self.lesson / 'pot' + lesson_directory.mkdir(parents=True) + first_blank = self.pot_content.index('\n') + self.header = self.pot_content[:first_blank + 1] + all_files = {} # To contain filename: [content] + rest_file = self.pot_content[first_blank + 1:] + file_sect = None + + for line in rest_file: + if not file_sect: + file_sect = extract_filename(line) + if file_sect not in all_files.keys(): + all_files[file_sect] = self.header + [line] + else: + all_files[file_sect].append(line) + if line == '\n': + file_sect = None + + # Write dictionary into files + for order_file, (file_sect, content_sect) in enumerate(all_files.items()): + with open(lesson_directory / f"{order_file:02d}__{file_sect}.pot", 'w') as section: + section.writelines(content_sect) + + # Generate transifex config file + tx_dir = lesson_directory.parent / '.tx' + tx_dir.mkdir() + config = configparser.ConfigParser() + config['main'] = {"host": "https://www.transifex.com"} + with open(tx_dir / 'config', 'w') as txconf: + config.write(txconf) + # TODO generate them directly + # for pot in pots: + # _set_source_file(tx_dir, self.lesson, 'en', pot) + + + + def join(self, source_dir, language): + # TODO check that filenames are there to be joint + # get all the files on source_dir/*.language.po + list_translations = glob.glob(f"{source_dir}/{language}/*.po") + list_translations.sort() + # read them all and join them with a single header # NOTE should we join the header info too? (eg., authors) + all_content = [] + translators = [] + last_touch = ('name', '"PO-Revision-Date: 2000-01-01 00:00:00+0000\\n"\n') + for file_translated in list_translations: + with open(file_translated, 'r') as section: + lines = section.readlines() + header = lines[:lines.index('\n') + 1] # we can use the last header as a template. + porev_line = list(filter(lambda x: 'Revision-Date' in x, header))[0] + potrans_line = list(filter(lambda x: 'Last' in x, header))[0] + touch = self._extract_date_po(porev_line) + if touch > self._extract_date_po(last_touch[1]): + last_touch = (potrans_line, porev_line) + lines = lines[lines.index('\n') + 1:] + ['\n'] + all_content.extend(lines) + translators_pos = header.index('# Translators:\n') + translators.extend(header[translators_pos + 1: header.index('# \n', translators_pos + 1)]) + + # find line with last revision date and replace it. + # NOTE Transifex is not updating that field! + header[header.index(porev_line)] = last_touch[1] + header[header.index(porev_line) + 1] = last_touch[0] + + # get unique and sorted names of translators + translators = sorted(set(translators)) + # FIXME add dots after each year for each translators + start = header.index("# Translators:\n") + end = header.index("# \n", start + 1) + header[start + 1: end] = translators + + all_content = header + all_content + + # path from the original filename + path_filename = Path(self.filename).parent + # Write file next to original with the language key. + with open(path_filename / f"{self.lesson}.{language}.po", 'w') as full_translation: + full_translation.writelines(all_content) + + def _extract_date_po(self, line): + title, date, time = line.split() + time = time.split('\\n"')[0] # removes the inside and outside linebreak + seconds_exist = time.count(":") == 2 + if not seconds_exist: + time, zone = time.split('+') + time = time + ":00" + time = "+".join([time, zone]) + + return datetime.datetime.strptime(f"{date} {time}", "%Y-%m-%d %H:%M:%S%z") + +if __name__ == "__main__": + command = ArgumentParser(description="Breaks a pot files into smaller chunks for better management for the translators.") + command.add_argument('filename', help="pot file to be split.") + command.add_argument('--join', '-j', dest='source', help="source directory from where to join split files") + command.add_argument('--lang', '-l', dest='language', help="which language you want to combine") + arguments = command.parse_args() + + pof = Pofiles(arguments.filename) + + if arguments.source and not arguments.language: + command.error("--join requires --lang") + + if arguments.source and arguments.language: + pof.join(arguments.source, arguments.language) + else: + pof.split() diff --git a/helpers/test_splitpot.py b/helpers/test_splitpot.py new file mode 100644 index 00000000..36a2eb82 --- /dev/null +++ b/helpers/test_splitpot.py @@ -0,0 +1,14 @@ +from pytest import raises + +from splitpot import extract_filename + +def test_extract_filename(): + line = '#: this/is/a/file:43' + assert extract_filename(line) == "file" + line = '#: this/is/a/file1.md:43' + assert extract_filename(line) == "file1.md" + +def test_extract_filename_wrong(): + line = '$: this is not a good line' + with raises(TypeError, match=r'The current line is not one that contains a filename\.'): + extract_filename(line) diff --git a/helpers/trans2lesson.py b/helpers/trans2lesson.py new file mode 100644 index 00000000..13751562 --- /dev/null +++ b/helpers/trans2lesson.py @@ -0,0 +1,84 @@ +from argparse import ArgumentParser +from distutils import dir_util +import glob +import os +from pathlib import Path +import tempfile + +from git import Repo +from github import Github, GithubException + +import ipdb + +def create_repo_tmp(path_files, tmpdirname): + # 1 create tmp dir + print(tmpdirname) + # 2 move the files there + dir_util.copy_tree(path_files, tmpdirname) + # 3 create that dir as a repo + repo = Repo.init(tmpdirname) + repo.index.add(glob.glob(f'{tmpdirname}/**/*.md', recursive=True)) + repo.index.commit("First set of translations") + return repo + + +def init_gh(): + if os.environ['gh_access_token']: + g = Github(os.environ['gh_access_token']) + else: + # ask for user name and password + # g = Github(username, password) + raise NotImplementedError + github_user = g.get_user() + return g, github_user + +def extract_lesson_language(path_translation): + *_, lang, lesson = path_translation.split('/') + return (lang, lesson) +def convert_url(url, gh_user): + ourl = url.replace('://', + f"://{gh_user.login}:{os.environ['gh_access_token']}@") + return ourl + +def main(path_translation, path_lesson): + assert Path(path_translation).exists() and Path(path_lesson).exists(), \ + "Provided directories don't exist" + g, user = init_gh() + organization = g.get_organization("carpentries-i18n") + lang, lesson = extract_lesson_language(path_translation) + # 0) TODO what if this is not the first time? check whether lesson has already + # 1) create repo on tmp + with tempfile.TemporaryDirectory() as tmpdirname: + repo = create_repo_tmp(path_translation, tmpdirname) + # 2) create repo on GH and push + try: + gh_repo = organization.create_repo(f'{lesson}-{lang}', auto_init=False) + except GithubException as e: + if e.status == 422: + # Repository exists already + gh_repo = g.get_repo(f'carpentries-i18n/{lesson}-{lang}') + origin_url = convert_url(gh_repo.html_url, user) + origin = repo.create_remote('origin', origin_url) + origin.push('master')#('+refs/heads/*:refs/remotes/origin/*') + # 3) create submodule on path lesson under _locale/lang + # before commit, check whether the repo is in the right branch. + lesson_repo = Repo(path_lesson) + locale = Path(path_lesson) / '_locale' + locale.mkdir(exist_ok=True) + # 4) create submodule from translation. + locale_sm = lesson_repo.create_submodule(name=f'{lang}', + path=f'_locale/{lang}', + url=gh_repo.html_url) + locale_sm.update() + lesson_repo.index.commit(f"Adds {lang} submodule") + # 5) push it! + lesson_repo.remotes.topush.push() + print(f"Repository {lesson_repo.remotes.origin.url} updated with {lang}.") + +if __name__ == "__main__": + parser = ArgumentParser(description="Move the translated files into its own repository and link it with the source") + parser.add_argument('path_translation', help='the path to the generated md translated files') + parser.add_argument('path_lesson', help='the path to the source lesson') + arguments = parser.parse_args() + + main(arguments.path_translation, arguments.path_lesson) diff --git a/po/POTFILES.in b/po/POTFILES.in index 859994f5..e864ed1d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -5,13 +5,6 @@ README_en.md TranslatorGuidelines.md Translators.md admin.md -git.md -importing.md -lang.md -quickstart.md -quickstart_ja.md -rules.md -updating.md git-novice/CODE_OF_CONDUCT.md git-novice/CONTRIBUTING.md git-novice/LICENSE.md @@ -65,6 +58,9 @@ git-novice/aio.md git-novice/index.md git-novice/reference.md git-novice/setup.md +git.md +importing.md +lang.md make-novice/CODE_OF_CONDUCT.md make-novice/CONTRIBUTING.md make-novice/LICENSE.md @@ -100,6 +96,31 @@ make-novice/index.md make-novice/reference.md make-novice/setup.md po4gitbook/README.md +python-ecology-lesson/CODE_OF_CONDUCT.md +python-ecology-lesson/CONTRIBUTING.md +python-ecology-lesson/LICENSE.md +python-ecology-lesson/README.md +python-ecology-lesson/_episodes/00-before-we-start.md +python-ecology-lesson/_episodes/01-short-introduction-to-Python.md +python-ecology-lesson/_episodes/02-starting-with-data.md +python-ecology-lesson/_episodes/03-index-slice-subset.md +python-ecology-lesson/_episodes/04-data-types-and-format.md +python-ecology-lesson/_episodes/05-merging-data.md +python-ecology-lesson/_episodes/06-loops-and-functions.md +python-ecology-lesson/_episodes/07-visualization-ggplot-python.md +python-ecology-lesson/_episodes/08-putting-it-all-together.md +python-ecology-lesson/_episodes/09-working-with-sql.md +python-ecology-lesson/_extras/CONTRIBUTORS.md +python-ecology-lesson/_extras/about.md +python-ecology-lesson/_extras/discuss.md +python-ecology-lesson/_extras/extra_challenges.md +python-ecology-lesson/_extras/figures.md +python-ecology-lesson/_extras/guide.md +python-ecology-lesson/_extras/jupyter_notebooks.md +python-ecology-lesson/aio.md +python-ecology-lesson/index.md +python-ecology-lesson/reference.md +python-ecology-lesson/setup.md python-novice-gapminder/CODE_OF_CONDUCT.md python-novice-gapminder/CONTRIBUTING.md python-novice-gapminder/LICENSE.md @@ -184,6 +205,8 @@ python-novice-inflammation/fig/README.md python-novice-inflammation/index.md python-novice-inflammation/reference.md python-novice-inflammation/setup.md +quickstart.md +quickstart_ja.md r-novice-gapminder/CODE_OF_CONDUCT.md r-novice-gapminder/CONTRIBUTING.md r-novice-gapminder/LICENSE.md @@ -248,6 +271,7 @@ r-novice-inflammation/bin/boilerplate/setup.md r-novice-inflammation/index.md r-novice-inflammation/reference.md r-novice-inflammation/setup.md +rules.md shell-novice/CONDUCT.md shell-novice/CONTRIBUTING.md shell-novice/LICENSE.md @@ -306,3 +330,4 @@ sql-novice-survey/bin/boilerplate/setup.md sql-novice-survey/index.md sql-novice-survey/reference.md sql-novice-survey/setup.md +updating.md diff --git a/po/python-ecology-lesson.pot b/po/python-ecology-lesson.pot new file mode 100644 index 00000000..f896eef6 --- /dev/null +++ b/po/python-ecology-lesson.pot @@ -0,0 +1,9468 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: i18n\n" +"Report-Msgid-Bugs-To: https://github.com/haiwen/seafile-docs/issues\n" +"POT-Creation-Date: 2019-08-20 20:51:45+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: python-ecology-lesson/CODE_OF_CONDUCT.md:1 +# Front Matter +msgid "---\n" +"layout: page\n" +"title: \"Contributor Code of Conduct\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/CODE_OF_CONDUCT.md:6 +msgid "As contributors and maintainers of this project,\n" +"we pledge to follow the [Carpentry Code of Conduct][coc]." +msgstr "" + +#: python-ecology-lesson/CODE_OF_CONDUCT.md:9 +msgid "Instances of abusive, harassing, or otherwise unacceptable behavior\n" +"may be reported by following our [reporting guidelines][coc-reporting]." +msgstr "" + +#: python-ecology-lesson/CODE_OF_CONDUCT.md:12 +#: python-ecology-lesson/_episodes/00-before-we-start.md:257 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:481 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:541 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:376 +#: python-ecology-lesson/_episodes/05-merging-data.md:424 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:695 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:596 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:375 +#: python-ecology-lesson/_episodes/09-working-with-sql.md:161 +#: python-ecology-lesson/_extras/figures.md:68 +#: python-ecology-lesson/_extras/guide.md:745 +#: python-ecology-lesson/index.md:38 +msgid "{% include links.md %}" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:1 +# header +msgid "# Contributing" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:3 +msgid "[The Carpentries][c-site] ([Software Carpentry][swc-site], [Data Carpentry][dc-site], and [Library Carpentry][lc-site]) are open source projects,\n" +"and we welcome contributions of all kinds:\n" +"new lessons,\n" +"fixes to existing material,\n" +"bug reports,\n" +"and reviews of proposed changes are all welcome." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:10 +# header +msgid "## Contributor Agreement" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:12 +msgid "By contributing,\n" +"you agree that we may redistribute your work under [our license](LICENSE.md).\n" +"In exchange,\n" +"we will address your issues and/or assess your change proposal as promptly as we can,\n" +"and help you become a member of our community.\n" +"Everyone involved in [The Carpentries][c-site]\n" +"agrees to abide by our [code of conduct](CODE_OF_CONDUCT.md)." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:20 +# header +msgid "## How to Contribute" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:22 +msgid "The easiest way to get started is to file an issue\n" +"to tell us about a spelling mistake,\n" +"some awkward wording,\n" +"or a factual error.\n" +"This is a good way to introduce yourself\n" +"and to meet some of our community members." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:29 +# ordered list +msgid "1. If you do not have a [GitHub][github] account," +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:30 +msgid " you can [send us comments by email][email].\n" +" However,\n" +" we will be able to respond more quickly if you use one of the other methods described below." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:34 +# ordered list +msgid "2. If you have a [GitHub][github] account," +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:35 +msgid " or are willing to [create one][github-join],\n" +" but do not know how to use Git,\n" +" you can report problems or suggest improvements by [creating an issue][issues].\n" +" This allows us to assign the item to someone\n" +" and to respond to it in a threaded discussion." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:41 +# ordered list +msgid "3. If you are comfortable with Git," +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:42 +msgid " and would like to add or change material,\n" +" you can submit a pull request (PR).\n" +" Instructions for doing this are [included below](#using-github)." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:46 +# header +msgid "## Where to Contribute" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:48 +# ordered list +msgid "1. If you wish to change this lesson," +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:49 +msgid " please work in ,\n" +" which can be viewed at ." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:52 +# ordered list +msgid "2. If you wish to change the example lesson," +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:53 +msgid " please work in ,\n" +" which documents the format of our lessons\n" +" and can be viewed at ." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:57 +# ordered list +msgid "3. If you wish to change the template used for workshop websites," +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:58 +msgid " please work in .\n" +" The home page of that repository explains how to set up workshop websites,\n" +" while the extra pages in \n" +" provide more background on our design choices." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:63 +# ordered list +msgid "4. If you wish to change CSS style files, tools," +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:64 +msgid " or HTML boilerplate for lessons or workshops stored in `_includes` or `_layouts`,\n" +" please work in ." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:67 +# header +msgid "## What to Contribute" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:69 +msgid "There are many ways to contribute,\n" +"from writing new exercises and improving existing ones\n" +"to updating or filling in the documentation\n" +"and submitting [bug reports][issues]\n" +"about things that don't work, aren't clear, or are missing.\n" +"If you are looking for ideas, please see the 'Issues' tab for\n" +"a list of issues associated with this repository,\n" +"or you may also look at the issues for [Data Carpentry][dc-issues],\n" +"[Software Carpentry][swc-issues], and [Library Carpentry][lc-issues] projects." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:79 +msgid "Comments on issues and reviews of pull requests are just as welcome:\n" +"we are smarter together than we are on our own.\n" +"Reviews from novices and newcomers are particularly valuable:\n" +"it's easy for people who have been using these lessons for a while\n" +"to forget how impenetrable some of this material can be,\n" +"so fresh eyes are always welcome." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:86 +# header +msgid "## What *Not* to Contribute" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:88 +msgid "Our lessons already contain more material than we can cover in a typical workshop,\n" +"so we are usually *not* looking for more concepts or tools to add to them.\n" +"As a rule,\n" +"if you want to introduce a new idea,\n" +"you must (a) estimate how long it will take to teach\n" +"and (b) explain what you would take out to make room for it.\n" +"The first encourages contributors to be honest about requirements;\n" +"the second, to think hard about priorities." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:97 +msgid "We are also not looking for exercises or other material that only run on one platform.\n" +"Our workshops typically contain a mixture of Windows, macOS, and Linux users;\n" +"in order to be usable,\n" +"our lessons must run equally well on all three." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:102 +# header +msgid "## Using GitHub" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:104 +msgid "If you choose to contribute via GitHub, you may want to look at\n" +"[How to Contribute to an Open Source Project on GitHub][how-contribute].\n" +"To manage changes, we follow [GitHub flow][github-flow].\n" +"Each lesson has two maintainers who review issues and pull requests or encourage others to do so.\n" +"The maintainers are community volunteers and have final say over what gets merged into the lesson.\n" +"To use the web interface for contributing to a lesson:" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:111 +# ordered list +msgid "1. Fork the originating repository to your GitHub profile." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:112 +# ordered list +msgid "2. Within your version of the forked repository, move to the `gh-pages` branch and" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:113 +msgid "create a new branch for each significant change being made.\n" +"3. Navigate to the file(s) you wish to change within the new branches and make revisions as required.\n" +"4. Commit all changed files within the appropriate branches.\n" +"5. Create individual pull requests from each of your changed branches\n" +"to the `gh-pages` branch within the originating repository.\n" +"6. If you receive feedback, make changes using your issue-specific branches of the forked\n" +"repository and the pull requests will update automatically.\n" +"7. Repeat as needed until all feedback has been addressed." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:122 +msgid "When starting work, please make sure your clone of the originating `gh-pages` branch is up-to-date\n" +"before creating your own revision-specific branch(es) from there.\n" +"Additionally, please only work from your newly-created branch(es) and *not*\n" +"your clone of the originating `gh-pages` branch.\n" +"Lastly, published copies of all the lessons are available in the `gh-pages` branch of the originating\n" +"repository for reference while revising." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:129 +# header +msgid "## Other Resources" +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:131 +msgid "General discussion of [Software Carpentry][swc-site] and [Data Carpentry][dc-site]\n" +"happens on the [discussion mailing list][discuss-list],\n" +"which everyone is welcome to join.\n" +"You can also [reach us by email][email]." +msgstr "" + +#: python-ecology-lesson/CONTRIBUTING.md:136 +msgid "[email]: mailto:admin@software-carpentry.org\n" +"[dc-issues]: https://github.com/issues?q=user%3Adatacarpentry\n" +"[dc-lessons]: http://datacarpentry.org/lessons/\n" +"[dc-site]: http://datacarpentry.org/\n" +"[discuss-list]: http://lists.software-carpentry.org/listinfo/discuss\n" +"[github]: https://github.com\n" +"[github-flow]: https://guides.github.com/introduction/flow/\n" +"[github-join]: https://github.com/join\n" +"[how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github\n" +"[issues]: https://guides.github.com/features/issues/\n" +"[swc-issues]: https://github.com/issues?q=user%3Aswcarpentry\n" +"[swc-lessons]: https://software-carpentry.org/lessons/\n" +"[swc-site]: https://software-carpentry.org/\n" +"[c-site]: https://carpentries.org/\n" +"[lc-site]: https://librarycarpentry.org/\n" +"[lc-issues]: https://github.com/issues?q=user%3Alibrarycarpentry" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:1 +# Front Matter +msgid "---\n" +"layout: page\n" +"title: \"Licenses\"\n" +"root: .\n" +"---" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:6 +# header +msgid "## Instructional Material" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:8 +msgid "All Software Carpentry, Data Carpentry, and Library Carpentry instructional material is\n" +"made available under the [Creative Commons Attribution\n" +"license][cc-by-human]. The following is a human-readable summary of\n" +"(and not a substitute for) the [full legal text of the CC BY 4.0\n" +"license][cc-by-legal]." +msgstr "" + +#: python-ecology-lesson/LICENSE.md:14 +msgid "You are free:" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:16 +# unordered list +msgid "* to **Share**---copy and redistribute the material in any medium or format" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:17 +# unordered list +msgid "* to **Adapt**---remix, transform, and build upon the material" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:19 +msgid "for any purpose, even commercially." +msgstr "" + +#: python-ecology-lesson/LICENSE.md:21 +msgid "The licensor cannot revoke these freedoms as long as you follow the\n" +"license terms." +msgstr "" + +#: python-ecology-lesson/LICENSE.md:24 +msgid "Under the following terms:" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:26 +# unordered list +msgid "* **Attribution**---You must give appropriate credit (mentioning that" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:27 +msgid " your work is derived from work that is Copyright © Software\n" +" Carpentry and, where practical, linking to\n" +" http://software-carpentry.org/), provide a [link to the\n" +" license][cc-by-human], and indicate if changes were made. You may do\n" +" so in any reasonable manner, but not in any way that suggests the\n" +" licensor endorses you or your use." +msgstr "" + +#: python-ecology-lesson/LICENSE.md:34 +msgid "**No additional restrictions**---You may not apply legal terms or\n" +"technological measures that legally restrict others from doing\n" +"anything the license permits. With the understanding that:" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:38 +msgid "Notices:" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:40 +# unordered list +msgid "* You do not have to comply with the license for elements of the" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:41 +msgid " material in the public domain or where your use is permitted by an\n" +" applicable exception or limitation.\n" +"* No warranties are given. The license may not give you all of the\n" +" permissions necessary for your intended use. For example, other\n" +" rights such as publicity, privacy, or moral rights may limit how you\n" +" use the material." +msgstr "" + +#: python-ecology-lesson/LICENSE.md:48 +# header +msgid "## Software" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:50 +msgid "Except where otherwise noted, the example programs and other software\n" +"provided by Software Carpentry and Data Carpentry are made available under the\n" +"[OSI][osi]-approved\n" +"[MIT license][mit-license]." +msgstr "" + +#: python-ecology-lesson/LICENSE.md:55 +msgid "Permission is hereby granted, free of charge, to any person obtaining\n" +"a copy of this software and associated documentation files (the\n" +"\"Software\"), to deal in the Software without restriction, including\n" +"without limitation the rights to use, copy, modify, merge, publish,\n" +"distribute, sublicense, and/or sell copies of the Software, and to\n" +"permit persons to whom the Software is furnished to do so, subject to\n" +"the following conditions:" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:63 +msgid "The above copyright notice and this permission notice shall be\n" +"included in all copies or substantial portions of the Software." +msgstr "" + +#: python-ecology-lesson/LICENSE.md:66 +msgid "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n" +"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n" +"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n" +"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n" +"LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n" +"OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n" +"WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." +msgstr "" + +#: python-ecology-lesson/LICENSE.md:74 +# header +msgid "## Trademark" +msgstr "" + +#: python-ecology-lesson/LICENSE.md:76 +msgid "\"Software Carpentry\" and \"Data Carpentry\" and their respective logos\n" +"are registered trademarks of [Community Initiatives][CI]." +msgstr "" + +#: python-ecology-lesson/LICENSE.md:79 +msgid "[cc-by-human]: https://creativecommons.org/licenses/by/4.0/\n" +"[cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode\n" +"[mit-license]: https://opensource.org/licenses/mit-license.html\n" +"[ci]: http://communityin.org/\n" +"[osi]: https://opensource.org" +msgstr "" + +#: python-ecology-lesson/README.md:1 +msgid "[![Create a Slack Account with us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/)\n" +"[![Slack Status](https://img.shields.io/badge/Slack_Channel-dc--ecology--py-E01563.svg)](https://swcarpentry.slack.com/messages/C9X44HCDS)" +msgstr "" + +#: python-ecology-lesson/README.md:5 +# header +msgid "## Data Carpentry Python Lessons with Ecological Data" +msgstr "" + +#: python-ecology-lesson/README.md:7 +msgid "This repository contains the Data Carpentry Python material based on ecological\n" +"data. Please see our [contribution guidelines](CONTRIBUTING.md) for information\n" +"on how to contribute updates, bug fixes, or other corrections." +msgstr "" + +#: python-ecology-lesson/README.md:11 +# header +msgid "### Maintainers" +msgstr "" + +#: python-ecology-lesson/README.md:13 +# unordered list +msgid "- April Wright ([@wrightaprilm](https://github.com/wrightaprilm))" +msgstr "" + +#: python-ecology-lesson/README.md:14 +# unordered list +msgid "- Tania Allard ([@trallard](https://github.com/trallard))" +msgstr "" + +#: python-ecology-lesson/README.md:15 +# unordered list +msgid "- Maxim Belkin ([@maxim-belkin](https://github.com/maxim-belkin))" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:1 +# Front Matter +msgid "---\n" +"title: Before we start\n" +"teaching: 30\n" +"exercises: 0\n" +"questions:\n" +" - \"What is Python and why should I learn it?\"\n" +"objectives:\n" +" - \"Describe the purpose of the editor, console, help, variable explorer and file explorer panes in\n" +" Spyder.\"\n" +" - \"Organize files and directories for a set of analyses as a Python project, and understand the\n" +" purpose of the working directory.\"\n" +" - \"Know where to find help.\"\n" +" - \"Demonstrate how to provide sufficient information for troubleshooting with the Python user\n" +" community.\"\n" +"keypoints:\n" +" - \"Python is an open source and platform independent programming language.\"\n" +" - \"SciPy ecosystem for Python provides the tools necessary for scientific computing.\"\n" +" - \"Jupyter Notebook and the Spyder IDE are great tools to code in and interact with Python. With\n" +" the large Python community it is easy to find help in the internet.\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:22 +msgid "
\n" +"## What is Python?\n" +"Python is a general purpose programming language that supports rapid development of data analytics\n" +"applications. The word \"Python\" is used to refer to both, the programming language and the tool\n" +"that executes the scripts written in Python language." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:28 +msgid "Its main advantages are:" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:30 +# unordered list +msgid "* Free" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:31 +# unordered list +msgid "* Open-source" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:32 +# unordered list +msgid "* Available on all major platforms (macOS, Linux, Windows)" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:33 +# unordered list +msgid "* Supported by Python Software Foundation" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:34 +# unordered list +msgid "* Supports multiple programming paradigms" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:35 +# unordered list +msgid "* Has large community" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:36 +# unordered list +msgid "* Rich ecosystem of third-party packages" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:38 +msgid "*So, why do you need Python for data analysis?*" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:40 +# unordered list +msgid "- **Easy to learn:**" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:41 +msgid "Python is easier to learn than other programming languages. This is important because lower barriers\n" +"mean it is easier for new members of the community to get up to speed." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:44 +# unordered list +msgid "- **Reproducibility:**" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:45 +msgid "Reproducibility is the ability to obtain the same results using the same dataset(s) and analysis." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:47 +msgid "Data analysis written as a Python script can be reproduced on any platform. Moreover, if you\n" +"collect more or correct existing data, you can quickly and easily re-run your analysis!" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:50 +msgid "An increasing number of journals and funding agencies expect analyses to be reproducible,\n" +"so knowing Python will give you an edge with these requirements." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:53 +# unordered list +msgid "- **Versatility:**" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:54 +msgid "Python is a versatile language that integrates with many existing applications to enable something\n" +"completely amazing. For example, one can use Python to generate manuscripts, so that if you need to\n" +"update your data, analysis procedure, or change something else, you can quickly regenerate all the\n" +"figures and your manuscript will be updated automatically." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:59 +msgid "Python can read text files, connect to databases, and many other data formats, on your computer or\n" +"on the web." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:62 +# unordered list +msgid "- **Interdisciplinary and extensible:**" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:63 +msgid "Python provides a framework that allows anyone to combine approaches from different research\n" +"(but not only) disciplines to best suit your analysis needs." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:66 +# unordered list +msgid "- **Python has a large and welcoming community:**" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:67 +msgid "Thousands of people use Python daily. Many of them are willing to help you through mailing lists and\n" +"websites, such as [Stack Overflow][stack-overflow] and [Anaconda community\n" +"portal][anaconda-community]." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:71 +# unordered list +msgid "- **Free and Open-Source Software (FOSS)... and Cross-Platform:**" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:72 +msgid "We know we have already said that but it is worth repeating." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:74 +msgid "
\n" +"## Knowing your way around Anaconda\n" +"[Anaconda][anaconda] distribution of Python includes a lot of its popular packages,\n" +"such as the IPython console, Jupyter Notebook, and Spyder IDE.\n" +"Have a quick look around the Anaconda Navigator. You can launch programs from the Navigator or use the command line." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:80 +msgid "The [Jupyter Notebook](https://jupyter.org) is an open-source web application that allows you to create\n" +"and share documents that allow one to easilty create documents that combine code, graphs, and narrative text.\n" +"[Spyder][spyder-ide] is an **Integrated Development Environment** that\n" +"allows one to write Python scripts and interact with the Python software from within a single interface." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:85 +msgid "Anaconda also comes with a package manager called [conda](https://conda.io/docs/),\n" +"which makes it easy to install and update additional packages." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:88 +msgid "
\n" +"## Research Project: Best Practices\n" +"It is a good idea to keep a set of related data, analyses, and text in a single folder.\n" +"All scripts and text files within this folder can then use relative paths to the data files.\n" +"Working this way makes it a lot easier to move around your project and share it with others." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:95 +# header +msgid "### Organizing your working directory" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:96 +msgid "Using a consistent folder structure across your projects will help you keep things organized,\n" +"and will also make it easy to find/file things in the future. This can be especially helpful\n" +"when you have multiple projects. In general, you may wish to create separate directories for\n" +"your scripts, data, and documents." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:101 +# unordered list +msgid "- **`data/`**: Use this folder to store your raw data. For the sake of transparency and provenance," +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:102 +msgid "you should always keep a copy of your **raw data**. If you need to cleanup data, do it\n" +"programmatically (_i.e._ with scripts) and make sure to separate cleaned up data from the raw data.\n" +"For example, you can store raw data in files `./data/raw/` and clean data in `./data/clean/`." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:106 +# unordered list +msgid "- **`documents/`**: Use this folder to store outlines, drafts, and other text." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:108 +# unordered list +msgid "- **`scripts/`**: Use this folder to store your (Python) scripts for data cleaning, analysis, and" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:109 +msgid "plotting that you use in this particular project." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:111 +msgid "You may need to create additional directories depending on your project needs, but these should form\n" +"the backbone of your project's directory. For this workshop, we will need a `data/` folder to store\n" +"our raw data, and we will later create a `data_output/` folder when we learn how to export data as\n" +"CSV files." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:117 +# header +msgid "## What is Programming and Coding?" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:119 +msgid "Programming is the process of writing _\"programs\"_ that a computer can execute and produce some\n" +"(useful) output.\n" +"Programming is a multi-step process that involves the following steps:" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:123 +# ordered list +msgid "1. Identifying the aspects of the real-world problem that can be solved computationally" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:124 +# ordered list +msgid "2. Identifying (the best) computational solution" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:125 +# ordered list +msgid "3. Implementing the solution in a specific computer language" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:126 +# ordered list +msgid "4. Testing, validating, and adjusting implemented solution." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:128 +msgid "While _\"Programming\"_ refers to all of the above steps,\n" +"_\"Coding\"_ refers to step 3 only: _\"Implementing the solution in a specific computer language\"_." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:131 +# header +msgid "#### If you are working with Jupyter notebook:" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:133 +msgid "You can type Python code into a code cell and then execute the code by pressing\n" +"Shift+Return.\n" +"Output will be printed directly under the input cell.\n" +"You can recognise a code cell by the `In[ ]:` at the beginning of the cell and output by `Out[ ]:`.\n" +"Pressing the __+__ button in the menu bar will add a new cell.\n" +"All your commands as well as any output will be saved with the notebook." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:140 +# header +msgid "#### If you are working with Spyder:" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:142 +msgid "You can either use the console or use script files (plain text files that contain your code). The\n" +"console pane (in Spyder, the bottom right panel) is the place where commands written in the Python\n" +"language can be typed and executed immediately by the computer. It is also where the results will be\n" +"shown. You can execute commands directly in the console by pressing Return, but they\n" +"will be \"lost\" when you close the session. Spyder uses the [IPython](http://ipython.org) console by\n" +"default." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:149 +msgid "Since we want our code and workflow to be reproducible, it is better to type the commands in\n" +"the script editor, and save them as a script. This way, there is a complete record of what we did,\n" +"and anyone (including our future selves!) can easily reproduce the results on their computer." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:153 +msgid "Spyder allows you to execute commands directly from the script editor by using the run buttons on\n" +"top. To run the entire script click _Run file_ or press F5, to run the current line\n" +"click _Run selection or current line_ or press F9, other run buttons allow to run script\n" +"cells or go into debug mode. When using F9, the command on the current line in the script\n" +"(indicated by the cursor) or all of the commands in the currently selected text will be sent to the\n" +"console and executed." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:160 +msgid "At some point in your analysis you may want to check the content of a variable or the structure of\n" +"an object, without necessarily keeping a record of it in your script. You can type these commands\n" +"and execute them directly in the console. Spyder provides the\n" +"Ctrl+Shift+E and Ctrl+Shift+I\n" +"shortcuts to allow you to jump between the script and the console panes." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:166 +msgid "If Python is ready to accept commands, the IPython console shows an `In [..]:` prompt with the\n" +"current console line number in `[]`. If it receives a command (by typing, copy-pasting or sent from\n" +"the script editor), Python will execute it, display the results in the `Out [..]:` cell, and come\n" +"back with a new `In [..]:` prompt waiting for new commands." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:171 +msgid "If Python is still waiting for you to enter more data because it isn’t complete yet, the console\n" +"will show a `...:` prompt. It means that you haven’t finished entering a complete command. This can\n" +"be because you have not typed a closing parenthesis (`)`, `]`, or `}`) or quotation mark. When this\n" +"happens, and you thought you finished typing your command, click inside the console window and press\n" +"Esc; this will cancel the incomplete command and return you to the `In [..]:` prompt." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:177 +# header +msgid "## How to learn more after the workshop?" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:179 +msgid "The material we cover during this workshop will give you an initial taste of how you can use Python\n" +"to analyze data for your own research. However, you will need to learn more to do advanced\n" +"operations such as cleaning your dataset, using statistical methods, or creating beautiful graphics.\n" +"The best way to become proficient and efficient at python, as with any other tool, is to use it to\n" +"address your actual research questions. As a beginner, it can feel daunting to have to write a\n" +"script from scratch, and given that many people make their code available online, modifying existing\n" +"code to suit your purpose might make it easier for you to get started." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:187 +# header +msgid "## Seeking help" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:189 +# unordered list +msgid "* check under the _Help_ menu" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:190 +# unordered list +msgid "* type `help()`" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:191 +# unordered list +msgid "* type `?object` or `help(object)` to get information about an object" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:192 +# unordered list +msgid "* [Python documentation][python-docs]" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:194 +msgid "Finally, a generic Google or internet search \"Python task\" will often either send you to the\n" +"appropriate module documentation or a helpful forum where someone else has already asked your\n" +"question." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:198 +msgid "I am stuck... I get an error message that I don’t understand.\n" +"Start by googling the error message. However, this doesn’t always work very well, because often,\n" +"package developers rely on the error catching provided by python. You end up with general error\n" +"messages that might not be very helpful to diagnose a problem (e.g. \"subscript out of bounds\"). If\n" +"the message is very generic, you might also include the name of the function or package you’re using\n" +"in your query." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:205 +msgid "However, you should check Stack Overflow. Search using the `python` tag. Most questions have already\n" +"been answered, but the challenge is to use the right words in the search to find the answers:\n" +"" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:209 +# header +msgid "### Asking for help" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:211 +msgid "The key to receiving help from someone is for them to rapidly grasp your problem. You should make it\n" +"as easy as possible to pinpoint where the issue might be." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:214 +msgid "Try to use the correct words to describe your problem. For instance, a package is not the same thing\n" +"as a library. Most people will understand what you meant, but others have really strong feelings\n" +"about the difference in meaning. The key point is that it can make things confusing for people\n" +"trying to help you. Be as precise as possible when describing your problem." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:219 +msgid "If possible, try to reduce what doesn’t work to a simple reproducible example. If you can reproduce\n" +"the problem using a very small data frame instead of your 50,000 rows and 10,000 columns one,\n" +"provide the small one with the description of your problem. When appropriate, try to generalize what\n" +"you are doing so even people who are not in your field can understand the question. For instance,\n" +"instead of using a subset of your real dataset, create a small (3 columns, 5 rows) generic one." +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:225 +# header +msgid "### Where to ask for help?" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:227 +# unordered list +msgid "* The person sitting next to you during the workshop. Don’t hesitate to talk to your neighbor during" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:228 +msgid "the workshop, compare your answers, and ask for help. You might also be interested in organizing\n" +"regular meetings following the workshop to keep learning from each other.\n" +"* Your friendly colleagues: if you know someone with more experience than you, they might be able and\n" +"willing to help you.\n" +"* [Stack Overflow][so-python]: if your question hasn’t been answered before and is well crafted,\n" +"chances are you will get an answer in less than 5 min. Remember to follow their guidelines on how to\n" +"ask a good question.\n" +"* [Python mailing lists][python-mailing-lists]" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:237 +# header +msgid "## More resources" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:239 +# unordered list +msgid "- [PyPI - the Python Package Index][pypi]" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:241 +# unordered list +msgid "- [The Hitchhiker's Guide to Python][python-guide]" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:243 +# unordered list +msgid "- [Dive into Python 3][dive-into-python3]" +msgstr "" + +#: python-ecology-lesson/_episodes/00-before-we-start.md:246 +msgid "[anaconda]: https://www.anaconda.com\n" +"[anaconda-community]: https://www.anaconda.com/community\n" +"[dive-into-python3]: https://finderiko.com/python-book\n" +"[pypi]: https://pypi.python.org/pypi\n" +"[python-docs]: https://www.python.org/doc\n" +"[python-guide]: https://docs.python-guide.org\n" +"[python-mailing-lists]: https://www.python.org/community/lists\n" +"[stack-overflow]: https://stackoverflow.com\n" +"[so-python]: https://stackoverflow.com/questions/tagged/python\n" +"[spyder-ide]: https://www.spyder-ide.org" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:1 +# Front Matter +msgid "---\n" +"title: Short Introduction to Programming in Python\n" +"teaching: 0\n" +"exercises: 0\n" +"questions:\n" +" - \"What is Python?\"\n" +" - \"Why should I learn Python?\"\n" +"objectives:\n" +" - \"Describe the advantages of using programming vs. completing repetitive tasks by hand.\"\n" +" - \"Define the following data types in Python: strings, integers, and floats.\"\n" +" - \"Perform mathematical operations in Python using basic operators.\"\n" +" - \"Define the following as it relates to Python: lists, tuples, and dictionaries.\"\n" +"keypoints:\n" +" - \"Python is an interpreted language which can be used interactively (executing one command at a time) or in scripting mode (executing a series of commands saved in file).\"\n" +" - \"One can assign a value to a variable in Python. Those variables can be of several types, such as string, integer, floating point and complex numbers.\"\n" +" - \"Lists and tuples are similar in that they are ordered lists of elements; they differ in that a tuple is immutable (cannot be changed).\"\n" +" - \"Dictionaries are unordered data structures that provide mappings between keys and values.\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:20 +# header +msgid "## Interpreter" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:22 +msgid "Python is an interpreted language which can be used in two ways:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:24 +# unordered list +msgid "* \"Interactively\": when you use it as an \"advanced calculator\" executing" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:25 +msgid " one command at a time. To start Python in this mode, simply execute `python`\n" +" on the command line:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:28 +# code block +msgid "~~~\n" +"$ python\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:31 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:69 +#: python-ecology-lesson/_extras/guide.md:27 +#: python-ecology-lesson/setup.md:68 +#: python-ecology-lesson/setup.md:88 +#: python-ecology-lesson/setup.md:98 +#: python-ecology-lesson/setup.md:108 +msgid "{: .language-bash}" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:33 +# code block +msgid "~~~\n" +"Python 3.5.1 (default, Oct 23 2015, 18:05:06)\n" +"[GCC 4.8.3] on linux2\n" +"Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n" +">>>\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:39 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:52 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:61 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:74 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:100 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:112 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:121 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:130 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:145 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:153 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:181 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:202 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:211 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:219 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:227 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:242 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:251 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:260 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:269 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:287 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:304 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:326 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:341 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:378 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:393 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:404 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:420 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:436 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:450 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:479 +#: python-ecology-lesson/_episodes/02-starting-with-data.md:88 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:291 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:340 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:101 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:115 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:128 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:223 +#: python-ecology-lesson/_episodes/05-merging-data.md:279 +#: python-ecology-lesson/_episodes/05-merging-data.md:358 +#: python-ecology-lesson/_episodes/05-merging-data.md:381 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:47 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:62 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:81 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:91 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:138 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:190 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:204 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:242 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:350 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:360 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:516 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:554 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:608 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:659 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:94 +#: python-ecology-lesson/_extras/guide.md:61 +#: python-ecology-lesson/_extras/guide.md:71 +#: python-ecology-lesson/_extras/guide.md:614 +# SC/DC Template label +msgid "{: .output}" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:41 +msgid "Chevrons `>>>` indicate an interactive prompt in Python, meaning that it is waiting for your\n" +"input." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:44 +# code block +msgid "~~~\n" +"2 + 2\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:47 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:87 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:197 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:297 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:321 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:357 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:429 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:53 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:76 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:85 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:103 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:124 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:169 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:182 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:200 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:219 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:230 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:262 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:281 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:309 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:326 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:333 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:372 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:392 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:399 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:406 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:465 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:487 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:501 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:510 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:522 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:89 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:96 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:110 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:123 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:137 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:175 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:188 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:205 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:218 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:280 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:290 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:300 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:308 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:344 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:359 +#: python-ecology-lesson/_episodes/05-merging-data.md:68 +#: python-ecology-lesson/_episodes/05-merging-data.md:91 +#: python-ecology-lesson/_episodes/05-merging-data.md:109 +#: python-ecology-lesson/_episodes/05-merging-data.md:128 +#: python-ecology-lesson/_episodes/05-merging-data.md:138 +#: python-ecology-lesson/_episodes/05-merging-data.md:194 +#: python-ecology-lesson/_episodes/05-merging-data.md:221 +#: python-ecology-lesson/_episodes/05-merging-data.md:256 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:42 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:53 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:77 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:86 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:120 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:159 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:259 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:271 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:333 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:345 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:355 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:395 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:406 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:411 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:437 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:454 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:510 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:601 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:52 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:87 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:104 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:120 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:163 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:175 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:188 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:203 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:220 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:235 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:253 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:292 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:307 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:357 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:367 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:380 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:394 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:415 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:444 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:525 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:542 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:560 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:588 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:57 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:78 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:107 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:116 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:159 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:166 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:186 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:210 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:241 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:263 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:336 +#: python-ecology-lesson/_episodes/09-working-with-sql.md:54 +#: python-ecology-lesson/_episodes/09-working-with-sql.md:82 +#: python-ecology-lesson/_episodes/09-working-with-sql.md:103 +#: python-ecology-lesson/_episodes/09-working-with-sql.md:150 +#: python-ecology-lesson/_extras/guide.md:66 +#: python-ecology-lesson/_extras/guide.md:132 +#: python-ecology-lesson/_extras/guide.md:139 +#: python-ecology-lesson/_extras/guide.md:155 +#: python-ecology-lesson/_extras/guide.md:247 +#: python-ecology-lesson/_extras/guide.md:317 +#: python-ecology-lesson/_extras/guide.md:357 +#: python-ecology-lesson/_extras/guide.md:411 +#: python-ecology-lesson/_extras/guide.md:430 +#: python-ecology-lesson/_extras/guide.md:444 +#: python-ecology-lesson/_extras/guide.md:462 +#: python-ecology-lesson/_extras/guide.md:470 +#: python-ecology-lesson/_extras/guide.md:491 +#: python-ecology-lesson/_extras/guide.md:505 +#: python-ecology-lesson/_extras/guide.md:524 +#: python-ecology-lesson/_extras/guide.md:627 +#: python-ecology-lesson/_extras/guide.md:658 +#: python-ecology-lesson/_extras/guide.md:672 +#: python-ecology-lesson/_extras/guide.md:699 +#: python-ecology-lesson/_extras/guide.md:732 +msgid "{: .language-python}" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:49 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:199 +# code block +msgid "~~~\n" +"4\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:54 +# code block +msgid "~~~\n" +"print(\"Hello World\")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:57 +msgid "{: .language-python}\n" +"~~~\n" +"Hello World\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:63 +# unordered list +msgid "* \"Scripting\" Mode: executing a series of \"commands\" saved in text file," +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:64 +msgid " usually with a `.py` extension after the name of your file:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:66 +# code block +msgid "~~~\n" +"$ python my_script.py\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:71 +# code block +msgid "~~~\n" +"Hello World\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:76 +# header +msgid "## Introduction to Python built-in data types" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:78 +# header +msgid "### Strings, integers, and floats" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:80 +msgid "One of the most basic things we can do in Python is assign values to variables:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:82 +# code block +msgid "~~~\n" +"text = \"Data Carpentry\" # An example of a string\n" +"number = 42 # An example of an integer\n" +"pi_value = 3.1415 # An example of a float\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:89 +msgid "Here we've assigned data to the variables `text`, `number` and `pi_value`,\n" +"using the assignment operator `=`. To review the value of a variable, we\n" +"can type the name of the variable into the interpreter and press Return:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:93 +# code block +msgid "~~~\n" +"text\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:96 +msgid "{: .language-python}\n" +"~~~\n" +"\"Data Carpentry\"\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:102 +msgid "Everything in Python has a type. To get the type of something, we can pass it\n" +"to the built-in function `type`:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:105 +# code block +msgid "~~~\n" +"type(text)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:108 +msgid "{: .language-python}\n" +"~~~\n" +"\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:114 +# code block +msgid "~~~\n" +"type(number)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:117 +msgid "{: .language-python}\n" +"~~~\n" +"\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:123 +# code block +msgid "~~~\n" +"type(pi_value)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:126 +msgid "{: .language-python}\n" +"~~~\n" +"\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:132 +msgid "The variable `text` is of type `str`, short for \"string\". Strings hold\n" +"sequences of characters, which can be letters, numbers, punctuation\n" +"or more exotic forms of text (even emoji!)." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:136 +msgid "We can also see the value of something using another built-in function, `print`:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:138 +# code block +msgid "~~~\n" +"print(text)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:141 +msgid "{: .language-python}\n" +"~~~\n" +"Data Carpentry\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:146 +# code block +msgid "~~~\n" +"print(number)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:149 +msgid "{: .language-python}\n" +"~~~\n" +"11\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:155 +msgid "This may seem redundant, but in fact it's the only way to display output in a script:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:157 +msgid "*example.py*\n" +"~~~\n" +"# A Python script file\n" +"# Comments in Python start with #\n" +"# The next line assigns the string \"Data Carpentry\" to the variable \"text\".\n" +"text = \"Data Carpentry\"" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:164 +# header +msgid "# The next line does nothing!" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:165 +msgid "text" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:167 +# header +msgid "# The next line uses the print function to print out the value we assigned to \"text\"" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:168 +msgid "print(text)\n" +"~~~\n" +"{: .language-python}" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:172 +msgid "*Running the script*\n" +"~~~\n" +"$ python example.py\n" +"~~~\n" +"{: .language-bash}" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:178 +# code block +msgid "~~~\n" +"Data Carpentry\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:183 +msgid "Notice that \"Data Carpentry\" is printed only once." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:185 +msgid "**Tip**: `print` and `type` are built-in functions in Python. Later in this\n" +"lesson, we will introduce methods and user-defined functions. The Python\n" +"documentation is excellent for reference on the differences between them." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:189 +# header +msgid "### Operators" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:191 +msgid "We can perform mathematical calculations in Python using the basic operators\n" +" `+, -, /, *, %`:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:194 +# code block +msgid "~~~\n" +"2 + 2 # Addition\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:204 +# code block +msgid "~~~\n" +"6 * 7 # Multiplication\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:207 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:475 +msgid "{: .language-python}\n" +"~~~\n" +"42\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:212 +# code block +msgid "~~~\n" +"2 ** 16 # Power\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:215 +msgid "{: .language-python}\n" +"~~~\n" +"65536\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:220 +# code block +msgid "~~~\n" +"13 % 5 # Modulo\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:223 +msgid "{: .language-python}\n" +"~~~\n" +"3\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:229 +msgid "We can also use comparison and logic operators:\n" +"`<, >, ==, !=, <=, >=` and statements of identity such as\n" +"`and, or, not`. The data type returned by this is\n" +"called a _boolean_." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:235 +# code block +msgid "~~~\n" +"3 > 4\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:238 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:265 +msgid "{: .language-python}\n" +"~~~\n" +"False\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:244 +# code block +msgid "~~~\n" +"True and True\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:247 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:256 +msgid "{: .language-python}\n" +"~~~\n" +"True\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:253 +# code block +msgid "~~~\n" +"True or False\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:262 +# code block +msgid "~~~\n" +"True and False\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:271 +# header +msgid "## Sequences: Lists and Tuples" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:273 +# header +msgid "### Lists" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:275 +msgid "**Lists** are a common data structure to hold an ordered sequence of\n" +"elements. Each element can be accessed by an index. Note that Python\n" +"indexes start with 0 instead of 1:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:279 +# code block +msgid "~~~\n" +"numbers = [1, 2, 3]\n" +"numbers[0]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:283 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:374 +msgid "{: .language-python}\n" +"~~~\n" +"1\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:289 +msgid "A `for` loop can be used to access the elements in a list or other Python data\n" +"structure one at a time:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:292 +# code block +msgid "~~~\n" +">>> for num in numbers:\n" +"... print(num)\n" +"...\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:299 +# code block +msgid "~~~\n" +"1\n" +"2\n" +"3\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:306 +msgid "**Indentation** is very important in Python. Note that the second line in the\n" +"example above is indented. Just like three chevrons `>>>` indicate an\n" +"interactive prompt in Python, the three dots `...` are Python's prompt for\n" +"multiple lines. This is Python's way of marking a block of code. [Note: you\n" +"do not type `>>>` or `...`.]" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:312 +msgid "To add elements to the end of a list, we can use the `append` method. Methods\n" +"are a way to interact with an object (a list, for example). We can invoke a\n" +"method using the dot `.` followed by the method name and a list of arguments\n" +"in parentheses. Let's look at an example using `append`:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:317 +# code block +msgid "~~~\n" +"numbers.append(4)\n" +"print(numbers)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:323 +# code block +msgid "~~~\n" +"[1, 2, 3, 4]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:328 +msgid "To find out what methods are available for an\n" +"object, we can use the built-in `help` command:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:331 +# code block +msgid "~~~\n" +"help(numbers)\n" +"\n" +"Help on list object:\n" +"\n" +"class list(object)\n" +" | list() -> new empty list\n" +" | list(iterable) -> new list initialized from iterable's items\n" +" ...\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:343 +# header +msgid "### Tuples" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:345 +msgid "A tuple is similar to a list in that it's an ordered sequence of elements.\n" +"However, tuples can not be changed once created (they are \"immutable\"). Tuples\n" +"are created by placing comma-separated values inside parentheses `()`." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:349 +# code block +msgid "~~~\n" +"# Tuples use parentheses\n" +"a_tuple = (1, 2, 3)\n" +"another_tuple = ('blue', 'green', 'red')\n" +"\n" +"# Note: lists use square brackets\n" +"a_list = [1, 2, 3]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:359 +# blockquote, which can be cascaded +msgid "> ## Tuples _vs._ Lists" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:360 +# blockquote, which can be cascaded +msgid "> 1. What happens when you execute `a_list[1] = 5`?" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:361 +# blockquote, which can be cascaded +msgid "> 2. What happens when you execute `a_tuple[2] = 5`?" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:362 +# blockquote, which can be cascaded +msgid "> 3. What does `type(a_tuple)` tell you about `a_tuple`?" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:363 +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:458 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:154 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:361 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:444 +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:539 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:236 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:324 +#: python-ecology-lesson/_episodes/05-merging-data.md:146 +#: python-ecology-lesson/_episodes/05-merging-data.md:408 +#: python-ecology-lesson/_episodes/05-merging-data.md:422 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:104 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:298 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:372 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:480 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:575 +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:693 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:141 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:276 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:345 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:486 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:506 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:573 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:218 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:327 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:357 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:373 +#: python-ecology-lesson/_episodes/09-working-with-sql.md:124 +#: python-ecology-lesson/_episodes/09-working-with-sql.md:159 +#: python-ecology-lesson/_extras/extra_challenges.md:46 +# SC/DC Template label +msgid "{: .challenge}" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:366 +# header +msgid "## Dictionaries" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:368 +msgid "A **dictionary** is a container that holds pairs of objects - keys and values." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:370 +# code block +msgid "~~~\n" +"translation = {'one': 1, 'two': 2}\n" +"translation['one']\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:380 +msgid "Dictionaries work a lot like lists - except that you index them with *keys*.\n" +"You can think about a key as a name for or a unique identifier for a set of values\n" +"in the dictionary. Keys can only have particular types - they have to be\n" +"\"hashable\". Strings and numeric types are acceptable, but lists aren't." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:385 +# code block +msgid "~~~\n" +"rev = {1: 'one', 2: 'two'}\n" +"rev[1]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:389 +msgid "{: .language-python}\n" +"~~~\n" +"'one'\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:395 +# code block +msgid "~~~\n" +"bad = {[1, 2, 3]: 3}\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:398 +msgid "{: .language-python}\n" +"~~~\n" +"Traceback (most recent call last):\n" +" File \"\", line 1, in \n" +"TypeError: unhashable type: 'list'\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:406 +msgid "In Python, a \"Traceback\" is an multi-line error block printed out for the\n" +"user." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:409 +msgid "To add an item to the dictionary we assign a value to a new key:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:411 +# code block +msgid "~~~\n" +"rev = {1: 'one', 2: 'two'}\n" +"rev[3] = 'three'\n" +"rev\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:416 +#: python-ecology-lesson/_extras/guide.md:57 +msgid "{: .language-python}\n" +"~~~\n" +"{1: 'one', 2: 'two', 3: 'three'}\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:422 +msgid "Using `for` loops with dictionaries is a little more complicated. We can do\n" +"this in two ways:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:425 +# code block +msgid "~~~\n" +"for key, value in rev.items():\n" +" print(key, '->', value)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:431 +# code block +msgid "~~~\n" +"1 -> one\n" +"2 -> two\n" +"3 -> three\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:438 +msgid "or" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:440 +# code block +msgid "~~~\n" +"for key in rev.keys():\n" +" print(key, '->', rev[key])\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:444 +msgid "{: .language-python}\n" +"~~~\n" +"1 -> one\n" +"2 -> two\n" +"3 -> three\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:452 +# blockquote, which can be cascaded +msgid "> ## Changing dictionaries" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:453 +msgid ">\n" +"> 1. First, print the value of the `rev` dictionary to the screen.\n" +"> 2. Reassign the value that corresponds to the key `2` so that it no longer\n" +"> reads \"two\" but instead \"apple-sauce\".\n" +"> 3. Print the value of `rev` to the screen again to see if the value has changed." +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:461 +# header +msgid "## Functions" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:463 +msgid "Defining a section of code as a function in Python is done using the `def`\n" +"keyword. For example a function that takes two arguments and returns their sum\n" +"can be defined as:" +msgstr "" + +#: python-ecology-lesson/_episodes/01-short-introduction-to-Python.md:467 +# code block +msgid "~~~\n" +"def add_function(a, b):\n" +" result = a + b\n" +" return result\n" +"\n" +"z = add_function(20, 22)\n" +"print(z)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:1 +# Front Matter +msgid "---\n" +"title: Starting With Data\n" +"teaching: 30\n" +"exercises: 30\n" +"questions:\n" +" - \"How can I import data in Python?\"\n" +" - \"What is Pandas?\"\n" +" - \"Why should I use Pandas to work with data?\"\n" +"objectives:\n" +" - \"Navigate the workshop directory and download a dataset.\"\n" +" - \"Explain what a library is and what libraries are used for.\"\n" +" - \"Describe what the Python Data Analysis Library (Pandas) is.\"\n" +" - \"Load the Python Data Analysis Library (Pandas).\"\n" +" - \"Use `read_csv` to read tabular data into Python.\"\n" +" - \"Describe what a DataFrame is in Python.\"\n" +" - \"Access and summarize data stored in a DataFrame.\"\n" +" - \"Define indexing as it relates to data structures.\"\n" +" - \"Perform basic mathematical operations and summary statistics on data in a Pandas DataFrame.\"\n" +" - \"Create simple plots.\"\n" +"keypoints:\n" +" - \"Libraries enable us to extend the functionality of Python.\" \n" +" - \"Pandas is a popular library for working with data.\"\n" +" - \"A Dataframe is a Pandas data structure that allows one to access data by column (name or index) or row.\"\n" +" - \"Aggregating data using the `groupby()` function enables you to generate useful summaries of data quickly.\"\n" +" - \"Plots can be created from DataFrames or subsets of data that have been generated with `groupby()`.\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:28 +# header +msgid "# Working With Pandas DataFrames in Python" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:30 +msgid "We can automate the process of performing data manipulations in Python. It's efficient to spend time\n" +"building the code to perform these tasks because once it's built, we can use it\n" +"over and over on different datasets that use a similar format. This makes our\n" +"methods easily reproducible. We can also easily share our code with colleagues\n" +"and they can replicate the same analysis." +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:36 +# header +msgid "### Starting in the same spot" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:38 +msgid "To help the lesson run smoothly, let's ensure everyone is in the same directory.\n" +"This should help us avoid path and file name issues. At this time please\n" +"navigate to the workshop directory. If you working in IPython Notebook be sure\n" +"that you start your notebook in the workshop directory." +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:43 +msgid "A quick aside that there are Python libraries like [OS Library][os-lib] that can work with our\n" +"directory structure, however, that is not our focus today." +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:46 +# header +msgid "### Our Data" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:48 +msgid "For this lesson, we will be using the Portal Teaching data, a subset of the data\n" +"from Ernst et al\n" +"[Long-term monitoring and experimental manipulation of a Chihuahuan Desert ecosystem near Portal,\n" +"Arizona, USA][ernst]." +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:53 +msgid "We will be using files from the [Portal Project Teaching Database][pptd].\n" +"This section will use the `surveys.csv` file that can be downloaded here:\n" +"[https://ndownloader.figshare.com/files/2292172][figshare-ndownloader]" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:57 +msgid "We are studying the species and weight of animals caught in sites in our study\n" +"area. The dataset is stored as a `.csv` file: each row holds information for a\n" +"single animal, and the columns represent:" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:61 +msgid "| Column | Description |\n" +"|------------------|------------------------------------|\n" +"| record_id | Unique id for the observation |\n" +"| month | month of observation |\n" +"| day | day of observation |\n" +"| year | year of observation |\n" +"| plot_id | ID of a particular site |\n" +"| species_id | 2-letter code |\n" +"| sex | sex of animal (\"M\", \"F\") |\n" +"| hindfoot_length | length of the hindfoot in mm |\n" +"| weight | weight of the animal in grams |" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:74 +msgid "The first few rows of our first file look like this:" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:76 +# code block +msgid "~~~\n" +"record_id,month,day,year,plot_id,species_id,sex,hindfoot_length,weight\n" +"1,7,16,1977,2,NL,M,32,\n" +"2,7,16,1977,3,NL,M,33,\n" +"3,7,16,1977,2,DM,F,37,\n" +"4,7,16,1977,7,DM,M,36,\n" +"5,7,16,1977,3,DM,M,35,\n" +"6,7,16,1977,1,PF,M,14,\n" +"7,7,16,1977,2,PE,F,,\n" +"8,7,16,1977,1,DM,M,37,\n" +"9,7,16,1977,1,DM,F,34,\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/02-starting-with-data.md:90 +# Front Matter +msgid "---\n" +"\n" +"## About Libraries\n" +"A library in Python contains a set of tools (called functions) that perform\n" +"tasks on our data. Importing a library is like getting a piece of lab equipment\n" +"out of a storage locker and setting it up on the bench for use in a project.\n" +"Once a library is set up, it can be used or called to perform many tasks.\n" +"\n" +"## Pandas in Python\n" +"One of the best options for working with tabular data in Python is to use the\n" +"[Python Data Analysis Library][pandas] (a.k.a. Pandas). The\n" +"Pandas library provides data structures, produces high quality plots with\n" +"[matplotlib][matplotlib] and integrates nicely with other libraries\n" +"that use [NumPy][numpy] (which is another Python library) arrays.\n" +"\n" +"Python doesn't load all of the libraries available to it by default. We have to\n" +"add an `import` statement to our code in order to use library functions. To import\n" +"a library, we use the syntax `import libraryName`. If we want to give the\n" +"library a nickname to shorten the command, we can add `as nickNameHere`. An\n" +"example of importing the pandas library using the common nickname `pd` is below.\n" +"\n" +"\n" +"~~~\n" +"import pandas as pd\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"Each time we call a function that's in a library, we use the syntax\n" +"`LibraryName.FunctionName`. Adding the library name with a `.` before the\n" +"function name tells Python where to find the function. In the example above, we\n" +"have imported Pandas as `pd`. This means we don't have to type out `pandas` each\n" +"time we call a Pandas function.\n" +"\n" +"\n" +"# Reading CSV Data Using Pandas\n" +"\n" +"We will begin by locating and reading our survey data which are in CSV format. CSV stands for\n" +"Comma-Separated Values and is a common way store formatted data. Other symbols may also be used, so\n" +"you might see tab-separated, colon-separated or space separated files. It is quite easy to replace\n" +"one separator with another, to match your application. The first line in the file often has headers\n" +"to explain what is in each column. CSV (and other separators) make it easy to share data, and can be\n" +"imported and exported from many applications, including Microsoft Excel. For more details on CSV\n" +"files, see the [Data Organisation in Spreadsheets][spreadsheet-lesson5] lesson.\n" +"We can use Pandas' `read_csv` function to pull the file directly into a [DataFrame][pd-dataframe].\n" +"\n" +"## So What's a DataFrame?\n" +"\n" +"A DataFrame is a 2-dimensional data structure that can store data of different\n" +"types (including characters, integers, floating point values, factors and more)\n" +"in columns. It is similar to a spreadsheet or an SQL table or the `data.frame` in\n" +"R. A DataFrame always has an index (0-based). An index refers to the position of\n" +"an element in the data structure.\n" +"\n" +"~~~\n" +"# Note that pd.read_csv is used because we imported pandas as pd\n" +"pd.read_csv(\"data/surveys.csv\")\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"The above command yields the **output** below:\n" +"\n" +"~~~\n" +"record_id month day year plot_id species_id sex hindfoot_length weight\n" +"0 1 7 16 1977 2 NL M 32 NaN\n" +"1 2 7 16 1977 3 NL M 33 NaN\n" +"2 3 7 16 1977 2 DM F 37 NaN\n" +"3 4 7 16 1977 7 DM M 36 NaN\n" +"4 5 7 16 1977 3 DM M 35 NaN\n" +"...\n" +"35544 35545 12 31 2002 15 AH NaN NaN NaN\n" +"35545 35546 12 31 2002 15 AH NaN NaN NaN\n" +"35546 35547 12 31 2002 10 RM F 15 14\n" +"35547 35548 12 31 2002 7 DO M 36 51\n" +"35548 35549 12 31 2002 5 NaN NaN NaN NaN\n" +"\n" +"[35549 rows x 9 columns]\n" +"~~~\n" +"{: .output}\n" +"\n" +"We can see that there were 35,549 rows parsed. Each row has 9\n" +"columns. The first column is the index of the DataFrame. The index is used to\n" +"identify the position of the data, but it is not an actual column of the DataFrame.\n" +"It looks like the `read_csv` function in Pandas read our file properly. However,\n" +"we haven't saved any data to memory so we can work with it. We need to assign the\n" +"DataFrame to a variable. Remember that a variable is a name for a value, such as `x`,\n" +"or `data`. We can create a new object with a variable name by assigning a value to it using `=`.\n" +"\n" +"Let's call the imported survey data `surveys_df`:\n" +"\n" +"~~~\n" +"surveys_df = pd.read_csv(\"data/surveys.csv\")\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"Notice when you assign the imported DataFrame to a variable, Python does not\n" +"produce any output on the screen. We can view the value of the `surveys_df`\n" +"object by typing its name into the Python command prompt.\n" +"\n" +"~~~\n" +"surveys_df\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"which prints contents like above.\n" +"\n" +"Note: if the output is too wide to print on your narrow terminal window, you may see something\n" +"slightly different as the large set of data scrolls past. You may see simply the last column\n" +"of data:\n" +"~~~\n" +"17 NaN\n" +"18 NaN\n" +"19 NaN\n" +"20 NaN\n" +"21 NaN\n" +"22 NaN\n" +"23 NaN\n" +"24 NaN\n" +"25 NaN\n" +"26 NaN\n" +"27 NaN\n" +"28 NaN\n" +"29 NaN\n" +"... ...\n" +"35519 36.0\n" +"35520 48.0\n" +"35521 45.0\n" +"35522 44.0\n" +"35523 27.0\n" +"35524 26.0\n" +"35525 24.0\n" +"35526 43.0\n" +"35527 NaN\n" +"35528 25.0\n" +"35529 NaN\n" +"35530 NaN\n" +"35531 43.0\n" +"35532 48.0\n" +"35533 56.0\n" +"35534 53.0\n" +"35535 42.0\n" +"35536 46.0\n" +"35537 31.0\n" +"35538 68.0\n" +"35539 23.0\n" +"35540 31.0\n" +"35541 29.0\n" +"35542 34.0\n" +"35543 NaN\n" +"35544 NaN\n" +"35545 NaN\n" +"35546 14.0\n" +"35547 51.0\n" +"35548 NaN\n" +"\n" +"[35549 rows x 9 columns]\n" +"~~~\n" +"{: .output}\n" +"\n" +"Never fear, all the data is there, if you scroll up. Selecting just a few rows, so it is\n" +"easier to fit on one window, you can see that pandas has neatly formatted the data to fit\n" +"our screen:\n" +"\n" +"~~~\n" +"surveys_df.head() # The head() method displays the first several lines of a file. It\n" +" # is discussed below.\n" +"~~~\n" +"{: .language-python}\n" +"~~~\n" +" record_id month day year plot_id species_id sex hindfoot_length \\\n" +"5 6 7 16 1977 1 PF M 14.0\n" +"6 7 7 16 1977 2 PE F NaN\n" +"7 8 7 16 1977 1 DM M 37.0\n" +"8 9 7 16 1977 1 DM F 34.0\n" +"9 10 7 16 1977 6 PF F 20.0\n" +"\n" +" weight\n" +"5 NaN\n" +"6 NaN\n" +"7 NaN\n" +"8 NaN\n" +"9 NaN\n" +"~~~\n" +"{: .output}\n" +"\n" +"## Exploring Our Species Survey Data\n" +"\n" +"Again, we can use the `type` function to see what kind of thing `surveys_df` is:\n" +"\n" +"~~~\n" +"type(surveys_df)\n" +"~~~\n" +"{: .language-python}\n" +"~~~\n" +"\n" +"~~~\n" +"{: .output}\n" +"\n" +"As expected, it's a DataFrame (or, to use the full name that Python uses to refer\n" +"to it internally, a `pandas.core.frame.DataFrame`).\n" +"\n" +"What kind of things does `surveys_df` contain? DataFrames have an attribute\n" +"called `dtypes` that answers this:\n" +"\n" +"~~~\n" +"surveys_df.dtypes\n" +"~~~\n" +"{: .language-python}\n" +"~~~\n" +"record_id int64\n" +"month int64\n" +"day int64\n" +"year int64\n" +"plot_id int64\n" +"species_id object\n" +"sex object\n" +"hindfoot_length float64\n" +"weight float64\n" +"dtype: object\n" +"~~~\n" +"{: .output}\n" +"\n" +"All the values in a column have the same type. For example, months have type\n" +"`int64`, which is a kind of integer. Cells in the month column cannot have\n" +"fractional values, but the weight and hindfoot_length columns can, because they\n" +"have type `float64`. The `object` type doesn't have a very helpful name, but in\n" +"this case it represents strings (such as 'M' and 'F' in the case of sex).\n" +"\n" +"We'll talk a bit more about what the different formats mean in a different lesson.\n" +"\n" +"### Useful Ways to View DataFrame objects in Python\n" +"\n" +"There are many ways to summarize and access the data stored in DataFrames,\n" +"using attributes and methods provided by the DataFrame object.\n" +"\n" +"To access an attribute, use the DataFrame object name followed by the attribute\n" +"name `df_object.attribute`. Using the DataFrame `surveys_df` and attribute\n" +"`columns`, an index of all the column names in the DataFrame can be accessed\n" +"with `surveys_df.columns`.\n" +"\n" +"Methods are called in a similar fashion using the syntax `df_object.method()`.\n" +"As an example, `surveys_df.head()` gets the first few rows in the DataFrame\n" +"`surveys_df` using **the `head()` method**. With a method, we can supply extra\n" +"information in the parens to control behaviour.\n" +"\n" +"Let's look at the data using these.\n" +"\n" +"> ## Challenge - DataFrames\n" +">\n" +"> Using our DataFrame `surveys_df`, try out the attributes & methods below to see\n" +"> what they return.\n" +">\n" +"> 1. `surveys_df.columns`\n" +"> 2. `surveys_df.shape` Take note of the output of `shape` - what format does it\n" +"> return the shape of the DataFrame in?\n" +">\n" +"> HINT: [More on tuples, here][python-datastructures].\n" +"> 3. `surveys_df.head()` Also, what does `surveys_df.head(15)` do?\n" +"> 4. `surveys_df.tail()`\n" +"{: .challenge}\n" +"\n" +"\n" +"## Calculating Statistics From Data In A Pandas DataFrame\n" +"\n" +"We've read our data into Python. Next, let's perform some quick summary\n" +"statistics to learn more about the data that we're working with. We might want\n" +"to know how many animals were collected in each site, or how many of each\n" +"species were caught. We can perform summary stats quickly using groups. But\n" +"first we need to figure out what we want to group by.\n" +"\n" +"Let's begin by exploring our data:\n" +"\n" +"~~~\n" +"# Look at the column names\n" +"surveys_df.columns\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"which **returns**:\n" +"\n" +"~~~\n" +"Index(['record_id', 'month', 'day', 'year', 'plot_id', 'species_id', 'sex',\n" +" 'hindfoot_length', 'weight'],\n" +" dtype='object')\n" +"~~~\n" +"{: .output}\n" +"\n" +"Let's get a list of all the species. The `pd.unique` function tells us all of\n" +"the unique values in the `species_id` column.\n" +"\n" +"~~~\n" +"pd.unique(surveys_df['species_id'])\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"which **returns**:\n" +"\n" +"~~~\n" +"array(['NL', 'DM', 'PF', 'PE', 'DS', 'PP', 'SH', 'OT', 'DO', 'OX', 'SS',\n" +" 'OL', 'RM', nan, 'SA', 'PM', 'AH', 'DX', 'AB', 'CB', 'CM', 'CQ',\n" +" 'RF', 'PC', 'PG', 'PH', 'PU', 'CV', 'UR', 'UP', 'ZL', 'UL', 'CS',\n" +" 'SC', 'BA', 'SF', 'RO', 'AS', 'SO', 'PI', 'ST', 'CU', 'SU', 'RX',\n" +" 'PB', 'PL', 'PX', 'CT', 'US'], dtype=object)\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"> ## Challenge - Statistics\n" +">\n" +"> 1. Create a list of unique site ID's (\"plot_id\") found in the surveys data. Call it\n" +"> `site_names`. How many unique sites are there in the data? How many unique\n" +"> species are in the data?\n" +">\n" +"> 2. What is the difference between `len(site_names)` and `surveys_df['plot_id'].nunique()`?\n" +"{: .challenge}\n" +"\n" +"# Groups in Pandas\n" +"\n" +"We often want to calculate summary statistics grouped by subsets or attributes\n" +"within fields of our data. For example, we might want to calculate the average\n" +"weight of all individuals per site.\n" +"\n" +"We can calculate basic statistics for all records in a single column using the\n" +"syntax below:\n" +"\n" +"~~~\n" +"surveys_df['weight'].describe()\n" +"~~~\n" +"{: .language-python}\n" +"gives **output**\n" +"\n" +"~~~\n" +"count 32283.000000\n" +"mean 42.672428\n" +"std 36.631259\n" +"min 4.000000\n" +"25% 20.000000\n" +"50% 37.000000\n" +"75% 48.000000\n" +"max 280.000000\n" +"Name: weight, dtype: float64\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"We can also extract one specific metric if we wish:\n" +"\n" +"~~~\n" +"surveys_df['weight'].min()\n" +"surveys_df['weight'].max()\n" +"surveys_df['weight'].mean()\n" +"surveys_df['weight'].std()\n" +"surveys_df['weight'].count()\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"But if we want to summarize by one or more variables, for example sex, we can\n" +"use **Pandas' `.groupby` method**. Once we've created a groupby DataFrame, we\n" +"can quickly calculate summary statistics by a group of our choice.\n" +"\n" +"~~~\n" +"# Group data by sex\n" +"grouped_data = surveys_df.groupby('sex')\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"The **pandas function `describe`** will return descriptive stats including: mean,\n" +"median, max, min, std and count for a particular column in the data. Pandas'\n" +"`describe` function will only return summary values for columns containing\n" +"numeric data.\n" +"\n" +"~~~\n" +"# Summary statistics for all numeric columns by sex\n" +"grouped_data.describe()\n" +"# Provide the mean for each numeric column by sex\n" +"grouped_data.mean()\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"`grouped_data.mean()` **OUTPUT:**\n" +"\n" +"~~~\n" +" record_id month day year plot_id \\\n" +"sex\n" +"F 18036.412046 6.583047 16.007138 1990.644997 11.440854\n" +"M 17754.835601 6.392668 16.184286 1990.480401 11.098282\n" +"\n" +" hindfoot_length weight\n" +"sex\n" +"F 28.836780 42.170555\n" +"M 29.709578 42.995379\n" +"\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"The `groupby` command is powerful in that it allows us to quickly generate\n" +"summary stats.\n" +"\n" +"> ## Challenge - Summary Data\n" +">\n" +"> 1. How many recorded individuals are female `F` and how many male `M`\n" +"> 2. What happens when you group by two columns using the following syntax and\n" +"> then grab mean values:\n" +"> - `grouped_data2 = surveys_df.groupby(['plot_id','sex'])`\n" +"> - `grouped_data2.mean()`\n" +"> 3. Summarize weight values for each site in your data. HINT: you can use the\n" +"> following syntax to only create summary statistics for one column in your data\n" +"> `by_site['weight'].describe()`\n" +">\n" +">\n" +">> ## Did you get #3 right?\n" +">> **A Snippet of the Output from challenge 3 looks like:**\n" +">>\n" +">> ~~~\n" +">> site\n" +">> 1 count 1903.000000\n" +">> mean 51.822911\n" +">> std 38.176670\n" +">> min 4.000000\n" +">> 25% 30.000000\n" +">> 50% 44.000000\n" +">> 75% 53.000000\n" +">> max 231.000000\n" +">> ...\n" +">> ~~~\n" +">> {: .output}\n" +"> {: .solution}\n" +"{: .challenge}\n" +"\n" +"## Quickly Creating Summary Counts in Pandas\n" +"\n" +"Let's next count the number of samples for each species. We can do this in a few\n" +"ways, but we'll use `groupby` combined with **a `count()` method**.\n" +"\n" +"\n" +"~~~\n" +"# Count the number of samples by species\n" +"species_counts = surveys_df.groupby('species_id')['record_id'].count()\n" +"print(species_counts)\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"Or, we can also count just the rows that have the species \"DO\":\n" +"\n" +"~~~\n" +"surveys_df.groupby('species_id')['record_id'].count()['DO']\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"> ## Challenge - Make a list\n" +">\n" +"> What's another way to create a list of species and associated `count` of the\n" +"> records in the data? Hint: you can perform `count`, `min`, etc functions on\n" +"> groupby DataFrames in the same way you can perform them on regular DataFrames.\n" +"{: .challenge}\n" +"\n" +"## Basic Math Functions\n" +"\n" +"If we wanted to, we could perform math on an entire column of our data. For\n" +"example let's multiply all weight values by 2. A more practical use of this might\n" +"be to normalize the data according to a mean, area, or some other value\n" +"calculated from our data.\n" +"\n" +"~~~\n" +"# Multiply all weight values by 2\n" +"surveys_df['weight']*2\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"# Quick & Easy Plotting Data Using Pandas\n" +"\n" +"We can plot our summary stats using Pandas, too.\n" +"\n" +"~~~\n" +"# Make sure figures appear inline in Ipython Notebook\n" +"%matplotlib inline\n" +"# Create a quick bar chart\n" +"species_counts.plot(kind='bar');\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"![Weight by Species Site](../fig/countPerSpecies.png)\n" +"Count per species site\n" +"\n" +"We can also look at how many animals were captured in each site:\n" +"\n" +"~~~\n" +"total_count = surveys_df.groupby('plot_id')['record_id'].nunique()\n" +"# Let's plot that too\n" +"total_count.plot(kind='bar');\n" +"~~~\n" +"{: .language-python}\n" +"\n" +"> ## Challenge - Plots\n" +">\n" +"> 1. Create a plot of average weight across all species per site.\n" +"> 2. Create a plot of total males versus total females for the entire dataset.\n" +"{: .challenge}\n" +"\n" +"> ## Summary Plotting Challenge\n" +">\n" +"> Create a stacked bar plot, with weight on the Y axis, and the stacked variable\n" +"> being sex. The plot should show total weight by sex for each site. Some\n" +"> tips are below to help you solve this challenge:\n" +">\n" +"> * For more on Pandas plots, visit this [link][pandas-plot].\n" +"> * You can use the code that follows to create a stacked bar plot but the data to stack\n" +"> need to be in individual columns. Here's a simple example with some data where\n" +"> 'a', 'b', and 'c' are the groups, and 'one' and 'two' are the subgroups.\n" +">\n" +"> ~~~\n" +"> d = {'one' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']),'two' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}\n" +"> pd.DataFrame(d)\n" +"> ~~~\n" +"> {: .language-python }\n" +">\n" +"> shows the following data\n" +">\n" +"> ~~~\n" +"> one two\n" +"> a 1 1\n" +"> b 2 2\n" +"> c 3 3\n" +"> d NaN 4\n" +"> ~~~\n" +"> {: .output}\n" +">\n" +"> We can plot the above with\n" +">\n" +"> ~~~\n" +"> # Plot stacked data so columns 'one' and 'two' are stacked\n" +"> my_df = pd.DataFrame(d)\n" +"> my_df.plot(kind='bar',stacked=True,title=\"The title of my graph\")\n" +"> ~~~\n" +"> {: .language-python }\n" +">\n" +"> ![Stacked Bar Plot](../fig/stackedBar1.png)\n" +">\n" +"> * You can use the `.unstack()` method to transform grouped data into columns\n" +"> for each plotting. Try running `.unstack()` on some DataFrames above and see\n" +"> what it yields.\n" +">\n" +"> Start by transforming the grouped data (by site and sex) into an unstacked layout, then create\n" +"> a stacked plot.\n" +">\n" +">\n" +">> ## Solution to Summary Challenge\n" +">>\n" +">> First we group data by site and by sex, and then calculate a total for each site.\n" +">>\n" +">> ~~~\n" +">> by_site_sex = surveys_df.groupby(['plot_id','sex'])\n" +">> site_sex_count = by_site_sex['weight'].sum()\n" +">> ~~~\n" +">> {: .language-python}\n" +">>\n" +">> This calculates the sums of weights for each sex within each site as a table\n" +">>\n" +">> ~~~\n" +">> site sex\n" +">> plot_id sex\n" +">> 1 F 38253\n" +">> M 59979\n" +">> 2 F 50144\n" +">> M 57250\n" +">> 3 F 27251\n" +">> M 28253\n" +">> 4 F 39796\n" +">> M 49377\n" +">> \n" +">> ~~~\n" +">> {: .output}\n" +">>\n" +">> Below we'll use `.unstack()` on our grouped data to figure out the total weight that each sex contributed to each site.\n" +">>\n" +">> ~~~\n" +">> by_site_sex = surveys_df.groupby(['plot_id','sex'])\n" +">> site_sex_count = by_site_sex['weight'].sum()\n" +">> site_sex_count.unstack()\n" +">> ~~~\n" +">> {: .language-python }\n" +">>\n" +">> The `unstack` method above will display the following output:\n" +">>\n" +">> ~~~\n" +">> sex F M\n" +">> plot_id\n" +">> 1 38253 59979\n" +">> 2 50144 57250\n" +">> 3 27251 28253\n" +">> 4 39796 49377\n" +">> \n" +">> ~~~\n" +">> {: .output}\n" +">>\n" +">> Now, create a stacked bar plot with that data where the weights for each sex are stacked by site.\n" +">>\n" +">> Rather than display it as a table, we can plot the above data by stacking the values of each sex as follows:\n" +">>\n" +">> ~~~\n" +">> by_site_sex = surveys_df.groupby(['plot_id','sex'])\n" +">> site_sex_count = by_site_sex['weight'].sum()\n" +">> spc = site_sex_count.unstack()\n" +">> s_plot = spc.plot(kind='bar',stacked=True,title=\"Total weight by site and sex\")\n" +">> s_plot.set_ylabel(\"Weight\")\n" +">> s_plot.set_xlabel(\"Plot\")\n" +">> ~~~\n" +">> {: .language-python}\n" +">>\n" +">> ![Stacked Bar Plot](../fig/stackedBar.png)\n" +"> {: .solution}\n" +"{: .challenge}\n" +"\n" +"[ernst]: http://www.esapubs.org/archive/ecol/E090/118/default.htm\n" +"[figshare-ndownloader]: https://ndownloader.figshare.com/files/2292172\n" +"[os-lib]: https://docs.python.org/3/library/os.html\n" +"[matplotlib]: https://matplotlib.org\n" +"[numpy]: https://www.numpy.org/\n" +"[pandas]: https://pandas.pydata.org\n" +"[pandas-plot]: http://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html#basic-plotting-plot\n" +"[pd-dataframe]: https://pandas.pydata.org/pandas-docs/stable/getting_started/dsintro.html#dataframe\n" +"[pptd]: https://figshare.com/articles/Portal_Project_Teaching_Database/1314459\n" +"[python-datastructures]: https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences\n" +"[spreadsheet-lesson5]: http://www.datacarpentry.org/spreadsheet-ecology-lesson/05-exporting-data\n" +"\n" +"{% include links.md %}\n" +"" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:1 +# Front Matter +msgid "---\n" +"title: Indexing, Slicing and Subsetting DataFrames in Python\n" +"teaching: 30\n" +"exercises: 30\n" +"questions:\n" +" - \"How can I access specific data within my data set?\"\n" +" - \"How can Python and Pandas help me to analyse my data?\"\n" +"objectives:\n" +" - \"Describe what 0-based indexing is.\"\n" +" - \"Manipulate and extract data using column headings and index locations.\"\n" +" - \"Employ slicing to select sets of data from a DataFrame.\"\n" +" - \"Employ label and integer-based indexing to select ranges of data in a dataframe.\"\n" +" - \"Reassign values within subsets of a DataFrame.\"\n" +" - \"Create a copy of a DataFrame.\"\n" +" - \"Query / select a subset of data using a set of criteria using the following operators:\n" +" `=`, `!=`, `>`, `<`, `>=`, `<=`.\"\n" +" - \"Locate subsets of data using masks.\"\n" +" - \"Describe BOOLEAN objects in Python and manipulate data using BOOLEANs.\"\n" +"keypoints:\n" +" - \"In Python, portions of data can be accessed using indices, slices, column headings, and\n" +" condition-based subsetting.\"\n" +" - \"Python uses 0-based indexing, in which the first element in a list, tuple or any other data\n" +" structure has an index of 0.\"\n" +" - \"Pandas enables common data exploration steps such as data indexing, slicing and conditional\n" +" subsetting.\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:28 +msgid "In the first episode of this lesson, we read a CSV file into a pandas' DataFrame. We learned how to:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:30 +# unordered list +msgid "- save a DataFrame to a named object," +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:31 +# unordered list +msgid "- perform basic math on data," +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:32 +# unordered list +msgid "- calculate summary statistics, and" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:33 +# unordered list +msgid "- create plots based on the data we loaded into pandas." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:35 +msgid "In this lesson, we will explore ways to access different parts of the data using:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:37 +# unordered list +msgid "- indexing," +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:38 +# unordered list +msgid "- slicing, and" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:39 +# unordered list +msgid "- subsetting." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:41 +# header +msgid "## Loading our data" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:43 +msgid "We will continue to use the surveys dataset that we worked with in the last\n" +"episode. Let's reopen and read in the data again:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:46 +# code block +msgid "~~~\n" +"# Make sure pandas is loaded\n" +"import pandas as pd\n" +"\n" +"# Read in the survey CSV\n" +"surveys_df = pd.read_csv(\"data/surveys.csv\")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:55 +# header +msgid "## Indexing and Slicing in Python" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:57 +msgid "We often want to work with subsets of a **DataFrame** object. There are\n" +"different ways to accomplish this including: using labels (column headings),\n" +"numeric ranges, or specific x,y index locations." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:62 +# header +msgid "## Selecting data using Labels (Column Headings)" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:64 +msgid "We use square brackets `[]` to select a subset of a Python object. For example,\n" +"we can select all data from a column named `species_id` from the `surveys_df`\n" +"DataFrame by name. There are two ways to do this:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:68 +# code block +msgid "~~~\n" +"# TIP: use the .head() method we saw earlier to make output shorter\n" +"# Method 1: select a 'subset' of the data using the column name\n" +"surveys_df['species_id']\n" +"\n" +"# Method 2: use the column name as an 'attribute'; gives the same output\n" +"surveys_df.species_id\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:78 +msgid "We can also create a new object that contains only the data within the\n" +"`species_id` column as follows:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:81 +# code block +msgid "~~~\n" +"# Creates an object, surveys_species, that only contains the `species_id` column\n" +"surveys_species = surveys_df['species_id']\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:87 +msgid "We can pass a list of column names too, as an index to select columns in that\n" +"order. This is useful when we need to reorganize our data." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:90 +msgid "**NOTE:** If a column name is not contained in the DataFrame, an exception\n" +"(error) will be raised." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:93 +# code block +msgid "~~~\n" +"# Select the species and plot columns from the DataFrame\n" +"surveys_df[['species_id', 'plot_id']]\n" +"\n" +"# What happens when you flip the order?\n" +"surveys_df[['plot_id', 'species_id']]\n" +"\n" +"# What happens if you ask for a column that doesn't exist?\n" +"surveys_df['speciess']\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:105 +msgid "Python tells us what type of error it is in the traceback, at the bottom it says\n" +"`KeyError: 'speciess'` which means that `speciess` is not a valid column name (nor a valid key in\n" +"the related Python data type dictionary)." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:109 +# header +msgid "## Extracting Range based Subsets: Slicing" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:111 +# blockquote, which can be cascaded +msgid "> ## Reminder" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:112 +# blockquote, which can be cascaded +msgid "> Python uses 0-based indexing." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:113 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:129 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:139 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:177 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:343 +#: python-ecology-lesson/_extras/guide.md:79 +# SC/DC Template label +msgid "{: .callout}" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:115 +msgid "Let's remind ourselves that Python uses 0-based\n" +"indexing. This means that the first element in an object is located at position\n" +"0. This is different from other tools like R and Matlab that index elements\n" +"within objects starting at 1." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:120 +# code block +msgid "~~~\n" +"# Create a list of numbers:\n" +"a = [1, 2, 3, 4, 5]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:126 +msgid "![indexing diagram](../fig/slicing-indexing.png)\n" +"![slicing diagram](../fig/slicing-slicing.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:130 +# blockquote, which can be cascaded +msgid "> ## Challenge - Extracting data" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:131 +msgid ">\n" +"> 1. What value does the code below return?\n" +">\n" +"> ~~~\n" +"> a[0]\n" +"> ~~~\n" +"> {: .language-python }\n" +">\n" +"> 2. How about this:\n" +">\n" +"> ~~~\n" +"> a[5]\n" +"> ~~~\n" +"> {: .language-python }\n" +">\n" +"> 3. In the example above, calling `a[5]` returns an error. Why is that?\n" +">\n" +"> 4. What about?\n" +">\n" +"> ~~~\n" +"> a[len(a)]\n" +"> ~~~\n" +"> {: .language-python }" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:157 +# header +msgid "## Slicing Subsets of Rows in Python" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:159 +msgid "Slicing using the `[]` operator selects a set of rows and/or columns from a\n" +"DataFrame. To slice out a set of rows, you use the following syntax:\n" +"`data[start:stop]`. When slicing in pandas the start bound is included in the\n" +"output. The stop bound is one step BEYOND the row you want to select. So if you\n" +"want to select rows 0, 1 and 2 your code would look like this:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:165 +# code block +msgid "~~~\n" +"# Select rows 0, 1, 2 (row 3 is not selected)\n" +"surveys_df[0:3]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:171 +msgid "The stop bound in Python is different from what you might be used to in\n" +"languages like Matlab and R." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:174 +# code block +msgid "~~~\n" +"# Select the first 5 rows (rows 0, 1, 2, 3, 4)\n" +"surveys_df[:5]\n" +"\n" +"# Select the last element in the list\n" +"# (the slice starts at the last element, and ends at the end of the list)\n" +"surveys_df[-1:]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:184 +msgid "We can also reassign values within subsets of our DataFrame." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:186 +msgid "But before we do that, let's look at the difference between the concept of\n" +"copying objects and the concept of referencing objects in Python." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:189 +# header +msgid "## Copying Objects vs Referencing Objects in Python" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:191 +msgid "Let's start with an example:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:193 +# code block +msgid "~~~\n" +"# Using the 'copy() method'\n" +"true_copy_surveys_df = surveys_df.copy()\n" +"\n" +"# Using the '=' operator\n" +"ref_surveys_df = surveys_df\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:202 +msgid "You might think that the code `ref_surveys_df = surveys_df` creates a fresh\n" +"distinct copy of the `surveys_df` DataFrame object. However, using the `=`\n" +"operator in the simple statement `y = x` does **not** create a copy of our\n" +"DataFrame. Instead, `y = x` creates a new variable `y` that references the\n" +"**same** object that `x` refers to. To state this another way, there is only\n" +"**one** object (the DataFrame), and both `x` and `y` refer to it." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:209 +msgid "In contrast, the `copy()` method for a DataFrame creates a true copy of the\n" +"DataFrame." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:212 +msgid "Let's look at what happens when we reassign the values within a subset of the\n" +"DataFrame that references another DataFrame object:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:215 +# code block +msgid "~~~\n" +"# Assign the value `0` to the first three rows of data in the DataFrame\n" +"ref_surveys_df[0:3] = 0\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:221 +msgid "Let's try the following code:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:223 +# code block +msgid "~~~\n" +"# ref_surveys_df was created using the '=' operator\n" +"ref_surveys_df.head()\n" +"\n" +"# surveys_df is the original dataframe\n" +"surveys_df.head()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:232 +msgid "What is the difference between these two dataframes?" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:234 +msgid "When we assigned the first 3 columns the value of `0` using the\n" +"`ref_surveys_df` DataFrame, the `surveys_df` DataFrame is modified too.\n" +"Remember we created the reference `ref_survey_df` object above when we did\n" +"`ref_survey_df = surveys_df`. Remember `surveys_df` and `ref_surveys_df`\n" +"refer to the same exact DataFrame object. If either one changes the object,\n" +"the other will see the same changes to the reference object." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:241 +msgid "**To review and recap**:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:243 +# unordered list +msgid "- **Copy** uses the dataframe's `copy()` method" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:245 +msgid " ~~~\n" +" true_copy_surveys_df = surveys_df.copy()\n" +" ~~~\n" +" {: .language-python }\n" +"- A **Reference** is created using the `=` operator" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:251 +msgid " ~~~\n" +" ref_surveys_df = surveys_df\n" +" ~~~\n" +" {: .language-python }" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:256 +msgid "Okay, that's enough of that. Let's create a brand new clean dataframe from\n" +"the original data CSV file." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:259 +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:333 +# code block +msgid "~~~\n" +"surveys_df = pd.read_csv(\"data/surveys.csv\")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:264 +# header +msgid "## Slicing Subsets of Rows and Columns in Python" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:266 +msgid "We can select specific ranges of our data in both the row and column directions\n" +"using either label or integer-based indexing." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:269 +# unordered list +msgid "- `loc` is primarily *label* based indexing. *Integers* may be used but" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:270 +msgid " they are interpreted as a *label*.\n" +"- `iloc` is primarily *integer* based indexing" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:273 +msgid "To select a subset of rows **and** columns from our DataFrame, we can use the\n" +"`iloc` method. For example, we can select month, day and year (columns 2, 3\n" +"and 4 if we start counting at 1), like this:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:277 +# code block +msgid "~~~\n" +"# iloc[row slicing, column slicing]\n" +"surveys_df.iloc[0:3, 1:4]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:283 +msgid "which gives the **output**" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:285 +# code block +msgid "~~~\n" +" month day year\n" +"0 7 16 1977\n" +"1 7 16 1977\n" +"2 7 16 1977\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:293 +msgid "Notice that we asked for a slice from 0:3. This yielded 3 rows of data. When you\n" +"ask for 0:3, you are actually telling Python to start at index 0 and select rows\n" +"0, 1, 2 **up to but not including 3**." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:297 +msgid "Let's explore some other ways to index and select subsets of data:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:299 +# code block +msgid "~~~\n" +"# Select all columns for rows of index values 0 and 10\n" +"surveys_df.loc[[0, 10], :]\n" +"\n" +"# What does this do?\n" +"surveys_df.loc[0, ['species_id', 'plot_id', 'weight']]\n" +"\n" +"# What happens when you type the code below?\n" +"surveys_df.loc[[0, 10, 35549], :]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:311 +msgid "**NOTE**: Labels must be found in the DataFrame or you will get a `KeyError`." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:313 +msgid "Indexing by labels `loc` differs from indexing by integers `iloc`.\n" +"With `loc`, both the start bound and the stop bound are **inclusive**. When using\n" +"`loc`, integers *can* be used, but the integers refer to the\n" +"index label and not the position. For example, using `loc` and select 1:4\n" +"will get a different result than using `iloc` to select rows 1:4." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:319 +msgid "We can also select a specific data value using a row and\n" +"column location within the DataFrame and `iloc` indexing:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:322 +# code block +msgid "~~~\n" +"# Syntax for iloc indexing to finding a specific data element\n" +"dat.iloc[row, column]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:328 +msgid "In this `iloc` example," +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:330 +# code block +msgid "~~~\n" +"surveys_df.iloc[2, 6]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:335 +msgid "gives the **output**" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:337 +# code block +msgid "~~~\n" +"'F'\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:342 +msgid "Remember that Python indexing begins at 0. So, the index location [2, 6]\n" +"selects the element that is 3 rows down and 7 columns over in the DataFrame." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:347 +# blockquote, which can be cascaded +msgid "> ## Challenge - Range" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:348 +msgid ">\n" +"> 1. What happens when you execute:\n" +">\n" +"> - `surveys_df[0:1]`\n" +"> - `surveys_df[:4]`\n" +"> - `surveys_df[:-1]`\n" +">\n" +"> 2. What happens when you call:\n" +">\n" +"> - `surveys_df.iloc[0:4, 1:4]`\n" +"> - `surveys_df.loc[0:4, 1:4]`\n" +">\n" +"> - How are the two commands different?" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:364 +# header +msgid "## Subsetting Data using Criteria" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:366 +msgid "We can also select a subset of our data using criteria. For example, we can\n" +"select all rows that have a year value of 2002:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:369 +# code block +msgid "~~~\n" +"surveys_df[surveys_df.year == 2002]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:374 +msgid "Which produces the following output:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:376 +# code block +msgid "~~~\n" +"record_id month day year plot_id species_id sex hindfoot_length weight\n" +"33320 33321 1 12 2002 1 DM M 38 44\n" +"33321 33322 1 12 2002 1 DO M 37 58\n" +"33322 33323 1 12 2002 1 PB M 28 45\n" +"33323 33324 1 12 2002 1 AB NaN NaN NaN\n" +"33324 33325 1 12 2002 1 DO M 35 29\n" +"...\n" +"35544 35545 12 31 2002 15 AH NaN NaN NaN\n" +"35545 35546 12 31 2002 15 AH NaN NaN NaN\n" +"35546 35547 12 31 2002 10 RM F 15 14\n" +"35547 35548 12 31 2002 7 DO M 36 51\n" +"35548 35549 12 31 2002 5 NaN NaN NaN NaN\n" +"\n" +"[2229 rows x 9 columns]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:394 +msgid "Or we can select all rows that do not contain the year 2002:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:396 +# code block +msgid "~~~\n" +"surveys_df[surveys_df.year != 2002]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:401 +msgid "We can define sets of criteria too:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:403 +# code block +msgid "~~~\n" +"surveys_df[(surveys_df.year >= 1980) & (surveys_df.year <= 1985)]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:408 +# header +msgid "### Python Syntax Cheat Sheet" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:410 +msgid "We can use the syntax below when querying data by criteria from a DataFrame.\n" +"Experiment with selecting various subsets of the \"surveys\" data." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:413 +# unordered list +msgid "* Equals: `==`" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:414 +# unordered list +msgid "* Not equals: `!=`" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:415 +# unordered list +msgid "* Greater than, less than: `>` or `<`" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:416 +# unordered list +msgid "* Greater than or equal to `>=`" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:417 +# unordered list +msgid "* Less than or equal to `<=`" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:420 +# blockquote, which can be cascaded +msgid "> ## Challenge - Queries" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:421 +msgid ">\n" +"> 1. Select a subset of rows in the `surveys_df` DataFrame that contain data from\n" +"> the year 1999 and that contain weight values less than or equal to 8. How\n" +"> many rows did you end up with? What did your neighbor get?\n" +">\n" +"> 2. You can use the `isin` command in Python to query a DataFrame based upon a\n" +"> list of values as follows:\n" +">\n" +"> ~~~\n" +"> surveys_df[surveys_df['species_id'].isin([listGoesHere])]\n" +"> ~~~\n" +"> {: .language-python }\n" +">\n" +"> Use the `isin` function to find all plots that contain particular species\n" +"> in the \"surveys\" DataFrame. How many records contain these values?\n" +">\n" +"> 3. Experiment with other queries. Create a query that finds all rows with a\n" +"> weight value > or equal to 0.\n" +">\n" +"> 4. The `~` symbol in Python can be used to return the OPPOSITE of the\n" +"> selection that you specify in Python. It is equivalent to **is not in**.\n" +"> Write a query that selects all rows with sex NOT equal to 'M' or 'F' in\n" +"> the \"surveys\" data." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:447 +# header +msgid "# Using masks to identify a specific condition" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:449 +msgid "A **mask** can be useful to locate where a particular subset of values exist or\n" +"don't exist - for example, NaN, or \"Not a Number\" values. To understand masks,\n" +"we also need to understand `BOOLEAN` objects in Python." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:453 +msgid "Boolean values include `True` or `False`. For example," +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:455 +# code block +msgid "~~~\n" +"# Set x to 5\n" +"x = 5\n" +"\n" +"# What does the code below return?\n" +"x > 5\n" +"\n" +"# How about this?\n" +"x == 5\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:467 +msgid "When we ask Python whether `x` is greater than 5, it returns `False`.\n" +"This is Python's way to say \"No\". Indeed, the value of `x` is 5,\n" +"and 5 is not greater than 5." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:471 +msgid "To create a boolean mask:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:473 +# unordered list +msgid "- Set the True / False criteria (e.g. `values > 5 = True`)" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:474 +# unordered list +msgid "- Python will then assess each value in the object to determine whether the" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:475 +msgid " value meets the criteria (True) or not (False).\n" +"- Python creates an output object that is the same shape as the original\n" +" object, but with a `True` or `False` value for each index location." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:479 +msgid "Let's try this out. Let's identify all locations in the survey data that have\n" +"null (missing or NaN) data values. We can use the `isnull` method to do this.\n" +"The `isnull` method will compare each cell with a null value. If an element\n" +"has a null value, it will be assigned a value of `True` in the output object." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:484 +# code block +msgid "~~~\n" +"pd.isnull(surveys_df)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:489 +msgid "A snippet of the output is below:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:491 +# code block +msgid "~~~\n" +" record_id month day year plot_id species_id sex hindfoot_length weight\n" +"0 False False False False False False False False True\n" +"1 False False False False False False False False True\n" +"2 False False False False False False False False True\n" +"3 False False False False False False False False True\n" +"4 False False False False False False False False True\n" +"\n" +"[35549 rows x 9 columns]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:503 +msgid "To select the rows where there are null values, we can use\n" +"the mask as an index to subset our data as follows:" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:506 +# code block +msgid "~~~\n" +"# To select just the rows with NaN values, we can use the 'any()' method\n" +"surveys_df[pd.isnull(surveys_df).any(axis=1)]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:512 +msgid "Note that the `weight` column of our DataFrame contains many `null` or `NaN`\n" +"values. We will explore ways of dealing with this in Lesson 03." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:515 +msgid "We can run `isnull` on a particular column too. What does the code below do?" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:517 +# code block +msgid "~~~\n" +"# What does this do?\n" +"empty_weights = surveys_df[pd.isnull(surveys_df['weight'])]['weight']\n" +"print(empty_weights)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:524 +msgid "Let's take a minute to look at the statement above. We are using the Boolean\n" +"object `pd.isnull(surveys_df['weight'])` as an index to `surveys_df`. We are\n" +"asking Python to select rows that have a `NaN` value of weight." +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:529 +# blockquote, which can be cascaded +msgid "> ## Challenge - Putting it all together" +msgstr "" + +#: python-ecology-lesson/_episodes/03-index-slice-subset.md:530 +msgid ">\n" +"> 1. Create a new DataFrame that only contains observations with sex values that\n" +"> are **not** female or male. Assign each sex value in the new DataFrame to a\n" +"> new value of 'x'. Determine the number of null values in the subset.\n" +">\n" +"> 2. Create a new DataFrame that contains only observations that are of sex male\n" +"> or female and where weight values are greater than 0. Create a stacked bar\n" +"> plot of average weight by plot with male vs female values stacked for each\n" +"> plot." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:1 +# Front Matter +msgid "---\n" +"title: Data Types and Formats\n" +"teaching: 20\n" +"exercises: 25\n" +"questions:\n" +" - \"What types of data can be contained in a DataFrame?\"\n" +" - \"Why is the data type important?\"\n" +"objectives:\n" +" - \"Describe how information is stored in a Python DataFrame.\"\n" +" - \"Define the two main types of data in Python: text and numerics.\"\n" +" - \"Examine the structure of a DataFrame.\"\n" +" - \"Modify the format of values in a DataFrame.\"\n" +" - \"Describe how data types impact operations.\"\n" +" - \"Define, manipulate, and interconvert integers and floats in Python.\"\n" +" - \"Analyze datasets having missing/null values (NaN values).\"\n" +" - \"Write manipulated data to a file.\"\n" +"keypoints:\n" +" - \"Pandas uses other names for data types than Python, for example: `object` for textual data.\"\n" +" - \"A column in a DataFrame can only have one data type.\"\n" +" - \"The data type in a DataFrame’s single column can be checked using `dtype`.\"\n" +" - \"Make conscious decisions about how to manage missing data.\"\n" +" - \"A DataFrame can be saved to a CSV file using the `to_csv` function.\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:25 +msgid "The format of individual columns and rows will impact analysis performed on a\n" +"dataset read into python. For example, you can't perform mathematical\n" +"calculations on a string (text formatted data). This might seem obvious,\n" +"however sometimes numeric values are read into Python as strings. In this\n" +"situation, when you then try to perform calculations on the string-formatted\n" +"numeric data, you get an error." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:32 +msgid "In this lesson we will review ways to explore and better understand the\n" +"structure and format of our data." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:35 +# header +msgid "# Types of Data" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:37 +msgid "How information is stored in a\n" +"DataFrame or a Python object affects what we can do with it and the outputs of\n" +"calculations as well. There are two main types of data that we're explore in\n" +"this lesson: numeric and text data types." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:42 +# header +msgid "## Numeric Data Types" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:44 +msgid "Numeric data types include integers and floats. A **floating point** (known as a\n" +"float) number has decimal points even if that decimal point value is 0. For\n" +"example: 1.13, 2.0, 1234.345. If we have a column that contains both integers and\n" +"floating point numbers, Pandas will assign the entire column to the float data\n" +"type so the decimal points are not lost." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:50 +msgid "An **integer** will never have a decimal point. Thus if we wanted to store 1.13 as\n" +"an integer it would be stored as 1. Similarly, 1234.345 would be stored as 1234. You\n" +"will often see the data type `Int64` in Python which stands for 64 bit integer. The 64\n" +"simply refers to the memory allocated to store data in each cell which effectively\n" +"relates to how many digits it can store in each \"cell\". Allocating space ahead of time\n" +"allows computers to optimize storage and processing efficiency." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:57 +# header +msgid "## Text Data Type" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:59 +msgid "Text data type is known as Strings in Python, or Objects in Pandas. Strings can\n" +"contain numbers and / or characters. For example, a string might be a word, a\n" +"sentence, or several sentences. A Pandas object might also be a plot name like\n" +"'plot1'. A string can also contain or consist of numbers. For instance, '1234'\n" +"could be stored as a string. As could '10.23'. However **strings that contain\n" +"numbers can not be used for mathematical operations**!" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:66 +msgid "Pandas and base Python use slightly different names for data types. More on this\n" +"is in the table below:" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:69 +msgid "| Pandas Type | Native Python Type | Description |\n" +"|-------------|--------------------|-------------|\n" +"| object | string | The most general dtype. Will be assigned to your column if column has mixed types (numbers and strings). |\n" +"| int64 | int | Numeric characters. 64 refers to the memory allocated to hold this character. |\n" +"| float64 | float | Numeric characters with decimals. If a column contains numbers and NaNs (see below), pandas will default to float64, in case your missing value has a decimal. |\n" +"| datetime64, timedelta[ns] | N/A (but see the [datetime] module in Python's standard library) | Values meant to hold time data. Look into these for time series experiments. |" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:76 +msgid "[datetime]: http://doc.python.org/2/library/datetime.html" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:79 +# header +msgid "## Checking the format of our data" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:81 +msgid "Now that we're armed with a basic understanding of numeric and text data\n" +"types, let's explore the format of our survey data. We'll be working with the\n" +"same `surveys.csv` dataset that we've used in previous lessons." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:85 +# code block +msgid "~~~\n" +"# Note that pd.read_csv is used because we imported pandas as pd\n" +"surveys_df = pd.read_csv(\"data/surveys.csv\")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:91 +msgid "Remember that we can check the type of an object like this:" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:93 +# code block +msgid "~~~\n" +"type(surveys_df)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:98 +# code block +msgid "~~~\n" +"pandas.core.frame.DataFrame\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:103 +msgid "Next, let's look at the structure of our surveys data. In pandas, we can check\n" +"the type of one column in a DataFrame using the syntax\n" +"`dataFrameName[column_name].dtype`:" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:107 +# code block +msgid "~~~\n" +"surveys_df['sex'].dtype\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:112 +# code block +msgid "~~~\n" +"dtype('O')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:117 +msgid "A type 'O' just stands for \"object\" which in Pandas' world is a string\n" +"(text)." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:120 +# code block +msgid "~~~\n" +"surveys_df['record_id'].dtype\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:125 +# code block +msgid "~~~\n" +"dtype('int64')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:130 +msgid "The type `int64` tells us that Python is storing each value within this column\n" +"as a 64 bit integer. We can use the `dat.dtypes` command to view the data type\n" +"for each column in a DataFrame (all at once)." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:134 +# code block +msgid "~~~\n" +"surveys_df.dtypes\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:139 +msgid "which **returns**:" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:141 +# code block +msgid "~~~\n" +"record_id int64\n" +"month int64\n" +"day int64\n" +"year int64\n" +"plot_id int64\n" +"species_id object\n" +"sex object\n" +"hindfoot_length float64\n" +"weight float64\n" +"dtype: object\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:153 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:41 +msgid "{: .language-python }" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:155 +msgid "Note that most of the columns in our Survey data are of type `int64`. This means\n" +"that they are 64 bit integers. But the weight column is a floating point value\n" +"which means it contains decimals. The `species_id` and `sex` columns are objects which\n" +"means they contain strings." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:160 +# header +msgid "## Working With Integers and Floats" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:162 +msgid "So we've learned that computers store numbers in one of two ways: as integers or\n" +"as floating-point numbers (or floats). Integers are the numbers we usually count\n" +"with. Floats have fractional parts (decimal places). Let's next consider how\n" +"the data type can impact mathematical operations on our data. Addition,\n" +"subtraction, division and multiplication work on floats and integers as we'd expect." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:168 +# code block +msgid "~~~\n" +"print(5+5)\n" +"10\n" +"\n" +"print(24-4)\n" +"20\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:177 +msgid "If we divide one integer by another, we get a float.\n" +"The result on Python 3 is different than in Python 2, where the result is an\n" +"integer (integer division)." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:181 +# code block +msgid "~~~\n" +"print(5/9)\n" +"0.5555555555555556\n" +"\n" +"print(10/3)\n" +"3.3333333333333335\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:190 +msgid "We can also convert a floating point number to an integer or an integer to\n" +"floating point number. Notice that Python by default rounds down when it\n" +"converts from floating point to integer." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:194 +# code block +msgid "~~~\n" +"# Convert a to an integer\n" +"a = 7.83\n" +"int(a)\n" +"7\n" +"\n" +"# Convert b to a float\n" +"b = 7\n" +"float(b)\n" +"7.0\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:207 +# header +msgid "# Working With Our Survey Data" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:209 +msgid "Getting back to our data, we can modify the format of values within our data, if\n" +"we want. For instance, we could convert the `record_id` field to floating point\n" +"values." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:213 +# code block +msgid "~~~\n" +"# Convert the record_id field from an integer to a float\n" +"surveys_df['record_id'] = surveys_df['record_id'].astype('float64')\n" +"surveys_df['record_id'].dtype\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:220 +# code block +msgid "~~~\n" +"dtype('float64')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:225 +# blockquote, which can be cascaded +msgid "> ## Challenge - Changing Types" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:226 +msgid ">\n" +"> Try converting the column `plot_id` to floats using\n" +">\n" +"> ~~~\n" +"> surveys_df.plot_id.astype(\"float\")\n" +"> ~~~\n" +"> {: .language-python}\n" +">\n" +"> Next try converting `weight` to an integer. What goes wrong here? What is Pandas telling you?\n" +"> We will talk about some solutions to this later." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:238 +# header +msgid "## Missing Data Values - NaN" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:240 +msgid "What happened in the last challenge activity? Notice that this throws a value error:\n" +"`ValueError: Cannot convert NA to integer`. If we look at the `weight` column in the surveys\n" +"data we notice that there are NaN (**N**ot **a** **N**umber) values. **NaN** values are undefined\n" +"values that cannot be represented mathematically. Pandas, for example, will read\n" +"an empty cell in a CSV or Excel sheet as a NaN. NaNs have some desirable properties: if we\n" +"were to average the `weight` column without replacing our NaNs, Python would know to skip\n" +"over those cells." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:248 +# code block +msgid "~~~\n" +"surveys_df['weight'].mean()\n" +"42.672428212991356\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:252 +msgid "{: .language-python}\n" +"Dealing with missing data values is always a challenge. It's sometimes hard to\n" +"know why values are missing - was it because of a data entry error? Or data that\n" +"someone was unable to collect? Should the value be 0? We need to know how\n" +"missing values are represented in the dataset in order to make good decisions.\n" +"If we're lucky, we have some metadata that will tell us more about how null\n" +"values were handled." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:260 +msgid "For instance, in some disciplines, like Remote Sensing, missing data values are\n" +"often defined as -9999. Having a bunch of -9999 values in your data could really\n" +"alter numeric calculations. Often in spreadsheets, cells are left empty where no\n" +"data are available. Pandas will, by default, replace those missing values with\n" +"NaN. However it is good practice to get in the habit of intentionally marking\n" +"cells that have no data, with a no data value! That way there are no questions\n" +"in the future when you (or someone else) explores your data." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:268 +# header +msgid "### Where Are the NaN's?" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:270 +msgid "Let's explore the NaN values in our data a bit further. Using the tools we\n" +"learned in lesson 02, we can figure out how many rows contain NaN values for\n" +"weight. We can also create a new subset from our data that only contains rows\n" +"with weight values > 0 (i.e., select meaningful weight values):" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:275 +# code block +msgid "~~~\n" +"len(surveys_df[pd.isnull(surveys_df.weight)])\n" +"# How many rows have weight values?\n" +"len(surveys_df[surveys_df.weight> 0])\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:282 +msgid "We can replace all NaN values with zeroes using the `.fillna()` method (after\n" +"making a copy of the data so we don't lose our work):" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:285 +# code block +msgid "~~~\n" +"df1 = surveys_df.copy()\n" +"# Fill all NaN values with 0\n" +"df1['weight'] = df1['weight'].fillna(0)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:292 +msgid "However NaN and 0 yield different analysis results. The mean value when NaN\n" +"values are replaced with 0 is different from when NaN values are simply thrown\n" +"out or ignored." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:296 +# code block +msgid "~~~\n" +"df1['weight'].mean()\n" +"38.751976145601844\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:302 +msgid "We can fill NaN values with any value that we chose. The code below fills all\n" +"NaN values with a mean for all weight values." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:305 +# code block +msgid "~~~\n" +"df1['weight'] = surveys_df['weight'].fillna(surveys_df['weight'].mean())\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:310 +msgid "We could also chose to create a subset of our data, only keeping rows that do\n" +"not contain NaN values." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:313 +msgid "The point is to make conscious decisions about how to manage missing data. This\n" +"is where we think about how our data will be used and how these values will\n" +"impact the scientific conclusions made from the data." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:317 +msgid "Python gives us all of the tools that we need to account for these issues. We\n" +"just need to be cautious about how the decisions that we make impact scientific\n" +"results." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:321 +# blockquote, which can be cascaded +msgid "> ## Challenge - Counting" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:322 +# blockquote, which can be cascaded +msgid "> Count the number of missing values per column. Hint: The method .count() gives you" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:323 +# blockquote, which can be cascaded +msgid "> the number of non-NA observations per column. Try looking to the .isnull() method." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:326 +#: python-ecology-lesson/_episodes/05-merging-data.md:116 +# header +msgid "## Writing Out Data to CSV" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:328 +msgid "We've learned about using manipulating data to get desired outputs. But we've also discussed\n" +"keeping data that has been manipulated separate from our raw data. Something we might be interested\n" +"in doing is working with only the columns that have full data. First, let's reload the data so\n" +"we're not mixing up all of our previous manipulations." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:336 +msgid "{: .language-python}\n" +"Next, let's drop all the rows that contain missing values. We will use the command `dropna`.\n" +"By default, dropna removes rows that contain missing data for even just one column." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:340 +# code block +msgid "~~~\n" +"df_na = surveys_df.dropna()\n" +"\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:346 +msgid "If you now type `df_na`, you should observe that the resulting DataFrame has 30676 rows\n" +"and 9 columns, much smaller than the 35549 row original." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:349 +msgid "We can now use the `to_csv` command to do export a DataFrame in CSV format. Note that the code\n" +"below will by default save the data into the current working directory. We can\n" +"save it to a different folder by adding the foldername and a slash before the filename:\n" +"`df.to_csv('foldername/out.csv')`. We use 'index=False' so that\n" +"pandas doesn't include the index number for each line." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:355 +# code block +msgid "~~~\n" +"# Write DataFrame to CSV\n" +"df_na.to_csv('data_output/surveys_complete.csv', index=False)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:361 +msgid "We will use this data file later in the workshop. Check out your working directory to make\n" +"sure the CSV wrote out properly, and that you can open it! If you want, try to bring it\n" +"back into Python to make sure it imports properly." +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:366 +# header +msgid "## Recap" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:368 +msgid "What we've learned:" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:370 +# unordered list +msgid "+ How to explore the data types of columns within a DataFrame" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:371 +# unordered list +msgid "+ How to change the data type" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:372 +# unordered list +msgid "+ What NaN values are, how they might be represented, and what this means for your work" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:373 +# unordered list +msgid "+ How to replace NaN values, if desired" +msgstr "" + +#: python-ecology-lesson/_episodes/04-data-types-and-format.md:374 +# unordered list +msgid "+ How to use `to_csv` to write manipulated data to a file." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:1 +# Front Matter +msgid "---\n" +"title: Combining DataFrames with Pandas\n" +"teaching: 20\n" +"exercises: 25\n" +"questions:\n" +" - \"Can I work with data from multiple sources?\"\n" +" - \"How can I combine data from different data sets?\"\n" +"objectives:\n" +" - \"Combine data from multiple files into a single DataFrame using merge and concat.\"\n" +" - \"Combine two DataFrames using a unique ID found in both DataFrames.\"\n" +" - \"Employ `to_csv` to export a DataFrame in CSV format.\"\n" +" - \"Join DataFrames using common fields (join keys).\"\n" +"keypoints:\n" +" - \"Pandas' `merge` and `concat` can be used to combine subsets of a DataFrame, or even data from different files.\"\n" +" - \"`join` function combines DataFrames based on index or column.\"\n" +" - \"Joining two DataFrames can be done in multiple ways (left, right, and inner) depending on what data must be in the final DataFrame.\"\n" +" - \"`to_csv` can be used to write out DataFrames in CSV format.\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:20 +msgid "In many \"real world\" situations, the data that we want to use come in multiple\n" +"files. We often need to combine these files into a single DataFrame to analyze\n" +"the data. The pandas package provides [various methods for combining\n" +"DataFrames](http://pandas.pydata.org/pandas-docs/stable/merging.html) including\n" +"`merge` and `concat`." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:26 +msgid "To work through the examples below, we first need to load the species and\n" +"surveys files into pandas DataFrames. In iPython:" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:29 +# code block +msgid "~~~\n" +"import pandas as pd\n" +"surveys_df = pd.read_csv(\"data/surveys.csv\",\n" +" keep_default_na=False, na_values=[\"\"])\n" +"surveys_df\n" +"\n" +" record_id month day year plot species sex hindfoot_length weight\n" +"0 1 7 16 1977 2 NA M 32 NaN\n" +"1 2 7 16 1977 3 NA M 33 NaN\n" +"2 3 7 16 1977 2 DM F 37 NaN\n" +"3 4 7 16 1977 7 DM M 36 NaN\n" +"4 5 7 16 1977 3 DM M 35 NaN\n" +"... ... ... ... ... ... ... ... ... ...\n" +"35544 35545 12 31 2002 15 AH NaN NaN NaN\n" +"35545 35546 12 31 2002 15 AH NaN NaN NaN\n" +"35546 35547 12 31 2002 10 RM F 15 14\n" +"35547 35548 12 31 2002 7 DO M 36 51\n" +"35548 35549 12 31 2002 5 NaN NaN NaN NaN\n" +"\n" +"[35549 rows x 9 columns]\n" +"\n" +"species_df = pd.read_csv(\"data/species.csv\",\n" +" keep_default_na=False, na_values=[\"\"])\n" +"species_df\n" +" species_id genus species taxa\n" +"0 AB Amphispiza bilineata Bird\n" +"1 AH Ammospermophilus harrisi Rodent\n" +"2 AS Ammodramus savannarum Bird\n" +"3 BA Baiomys taylori Rodent\n" +"4 CB Campylorhynchus brunneicapillus Bird\n" +".. ... ... ... ...\n" +"49 UP Pipilo sp. Bird\n" +"50 UR Rodent sp. Rodent\n" +"51 US Sparrow sp. Bird\n" +"52 ZL Zonotrichia leucophrys Bird\n" +"53 ZM Zenaida macroura Bird\n" +"\n" +"[54 rows x 4 columns]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:70 +msgid "Take note that the `read_csv` method we used can take some additional options which\n" +"we didn't use previously. Many functions in Python have a set of options that\n" +"can be set by the user if needed. In this case, we have told pandas to assign\n" +"empty values in our CSV to NaN `keep_default_na=False, na_values=[\"\"]`.\n" +"[More about all of the read_csv options here.](http://pandas.pydata.org/pandas-docs/dev/generated/pandas.io.parsers.read_csv.html)" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:76 +# header +msgid "# Concatenating DataFrames" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:78 +msgid "We can use the `concat` function in pandas to append either columns or rows from\n" +"one DataFrame to another. Let's grab two subsets of our data to see how this\n" +"works." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:82 +# code block +msgid "~~~\n" +"# Read in first 10 lines of surveys table\n" +"survey_sub = surveys_df.head(10)\n" +"# Grab the last 10 rows\n" +"survey_sub_last10 = surveys_df.tail(10)\n" +"# Reset the index values to the second dataframe appends properly\n" +"survey_sub_last10=survey_sub_last10.reset_index(drop=True)\n" +"# drop=True option avoids adding new index column with old index values\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:93 +msgid "When we concatenate DataFrames, we need to specify the axis. `axis=0` tells\n" +"pandas to stack the second DataFrame under the first one. It will automatically\n" +"detect whether the column names are the same and will stack accordingly.\n" +"`axis=1` will stack the columns in the second DataFrame to the RIGHT of the\n" +"first DataFrame. To stack the data vertically, we need to make sure we have the\n" +"same columns and associated column format in both datasets. When we stack\n" +"horizonally, we want to make sure what we are doing makes sense (ie the data are\n" +"related in some way)." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:102 +# code block +msgid "~~~\n" +"# Stack the DataFrames on top of each other\n" +"vertical_stack = pd.concat([survey_sub, survey_sub_last10], axis=0)\n" +"\n" +"# Place the DataFrames side by side\n" +"horizontal_stack = pd.concat([survey_sub, survey_sub_last10], axis=1)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:111 +# header +msgid "### Row Index Values and Concat" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:112 +msgid "Have a look at the `vertical_stack` dataframe? Notice anything unusual?\n" +"The row indexes for the two data frames `survey_sub` and `survey_sub_last10`\n" +"have been repeated. We can reindex the new dataframe using the `reset_index()` method." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:118 +msgid "We can use the `to_csv` command to do export a DataFrame in CSV format. Note that the code\n" +"below will by default save the data into the current working directory. We can\n" +"save it to a different folder by adding the foldername and a slash to the file\n" +"`vertical_stack.to_csv('foldername/out.csv')`. We use the 'index=False' so that\n" +"pandas doesn't include the index number for each line." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:124 +# code block +msgid "~~~\n" +"# Write DataFrame to CSV\n" +"vertical_stack.to_csv('data_output/out.csv', index=False)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:130 +msgid "Check out your working directory to make sure the CSV wrote out properly, and\n" +"that you can open it! If you want, try to bring it back into Python to make sure\n" +"it imports properly." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:134 +# code block +msgid "~~~\n" +"# For kicks read our output back into Python and make sure all looks good\n" +"new_output = pd.read_csv('data_output/out.csv', keep_default_na=False, na_values=[\"\"])\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:140 +# blockquote, which can be cascaded +msgid "> ## Challenge - Combine Data" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:141 +msgid ">\n" +"> In the data folder, there are two survey data files: `survey2001.csv` and\n" +"> `survey2002.csv`. Read the data into Python and combine the files to make one\n" +"> new data frame. Create a plot of average plot weight by year grouped by sex.\n" +"> Export your results as a CSV and make sure it reads back into Python properly." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:148 +# header +msgid "# Joining DataFrames" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:150 +msgid "When we concatenated our DataFrames we simply added them to each other -\n" +"stacking them either vertically or side by side. Another way to combine\n" +"DataFrames is to use columns in each dataset that contain common values (a\n" +"common unique id). Combining DataFrames using a common field is called\n" +"\"joining\". The columns containing the common values are called \"join key(s)\".\n" +"Joining DataFrames in this way is often useful when one DataFrame is a \"lookup\n" +"table\" containing additional data that we want to include in the other." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:158 +msgid "NOTE: This process of joining tables is similar to what we do with tables in an\n" +"SQL database." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:161 +msgid "For example, the `species.csv` file that we've been working with is a lookup\n" +"table. This table contains the genus, species and taxa code for 55 species. The\n" +"species code is unique for each line. These species are identified in our survey\n" +"data as well using the unique species code. Rather than adding 3 more columns\n" +"for the genus, species and taxa to each of the 35,549 line Survey data table, we\n" +"can maintain the shorter table with the species information. When we want to\n" +"access that information, we can create a query that joins the additional columns\n" +"of information to the Survey data." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:170 +msgid "Storing data in this way has many benefits including:" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:172 +# ordered list +msgid "1. It ensures consistency in the spelling of species attributes (genus, species" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:173 +msgid " and taxa) given each species is only entered once. Imagine the possibilities\n" +" for spelling errors when entering the genus and species thousands of times!\n" +"2. It also makes it easy for us to make changes to the species information once\n" +" without having to find each instance of it in the larger survey data.\n" +"3. It optimizes the size of our data." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:180 +# header +msgid "## Joining Two DataFrames" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:182 +msgid "To better understand joins, let's grab the first 10 lines of our data as a\n" +"subset to work with. We'll use the `.head` method to do this. We'll also read\n" +"in a subset of the species table." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:186 +# code block +msgid "~~~\n" +"# Read in first 10 lines of surveys table\n" +"survey_sub = surveys_df.head(10)\n" +"\n" +"# Import a small subset of the species data designed for this part of the lesson.\n" +"# It is stored in the data folder.\n" +"species_sub = pd.read_csv('data/speciesSubset.csv', keep_default_na=False, na_values=[\"\"])\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:196 +msgid "In this example, `species_sub` is the lookup table containing genus, species, and\n" +"taxa names that we want to join with the data in `survey_sub` to produce a new\n" +"DataFrame that contains all of the columns from both `species_df` *and*\n" +"`survey_df`." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:202 +# header +msgid "## Identifying join keys" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:204 +msgid "To identify appropriate join keys we first need to know which field(s) are\n" +"shared between the files (DataFrames). We might inspect both DataFrames to\n" +"identify these columns. If we are lucky, both DataFrames will have columns with\n" +"the same name that also contain the same data. If we are less lucky, we need to\n" +"identify a (differently-named) column in each DataFrame that contains the same\n" +"information." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:211 +# code block +msgid "~~~\n" +">>> species_sub.columns\n" +"\n" +"Index([u'species_id', u'genus', u'species', u'taxa'], dtype='object')\n" +"\n" +">>> survey_sub.columns\n" +"\n" +"Index([u'record_id', u'month', u'day', u'year', u'plot_id', u'species_id',\n" +" u'sex', u'hindfoot_length', u'weight'], dtype='object')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:223 +msgid "In our example, the join key is the column containing the two-letter species\n" +"identifier, which is called `species_id`." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:226 +msgid "Now that we know the fields with the common species ID attributes in each\n" +"DataFrame, we are almost ready to join our data. However, since there are\n" +"[different types of joins](http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/), we\n" +"also need to decide which type of join makes sense for our analysis." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:231 +# header +msgid "## Inner joins" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:233 +msgid "The most common type of join is called an _inner join_. An inner join combines\n" +"two DataFrames based on a join key and returns a new DataFrame that contains\n" +"**only** those rows that have matching values in *both* of the original\n" +"DataFrames." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:238 +msgid "Inner joins yield a DataFrame that contains only rows where the value being\n" +"joins exists in BOTH tables. An example of an inner join, adapted from [this\n" +"page](http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/) is below:" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:242 +msgid "![Inner join -- courtesy of codinghorror.com](../fig/inner-join.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:244 +msgid "The pandas function for performing joins is called `merge` and an Inner join is\n" +"the default option:" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:247 +# code block +msgid "~~~\n" +"merged_inner = pd.merge(left=survey_sub,right=species_sub, left_on='species_id', right_on='species_id')\n" +"# In this case `species_id` is the only column name in both dataframes, so if we skipped `left_on`\n" +"# And `right_on` arguments we would still get the same result\n" +"\n" +"# What's the size of the output data?\n" +"merged_inner.shape\n" +"merged_inner\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:258 +# code block +msgid "~~~\n" +" record_id month day year plot_id species_id sex hindfoot_length \\\n" +"0 1 7 16 1977 2 NL M 32\n" +"1 2 7 16 1977 3 NL M 33\n" +"2 3 7 16 1977 2 DM F 37\n" +"3 4 7 16 1977 7 DM M 36\n" +"4 5 7 16 1977 3 DM M 35\n" +"5 8 7 16 1977 1 DM M 37\n" +"6 9 7 16 1977 1 DM F 34\n" +"7 7 7 16 1977 2 PE F NaN\n" +"\n" +" weight genus species taxa\n" +"0 NaN Neotoma albigula Rodent\n" +"1 NaN Neotoma albigula Rodent\n" +"2 NaN Dipodomys merriami Rodent\n" +"3 NaN Dipodomys merriami Rodent\n" +"4 NaN Dipodomys merriami Rodent\n" +"5 NaN Dipodomys merriami Rodent\n" +"6 NaN Dipodomys merriami Rodent\n" +"7 NaN Peromyscus eremicus Rodent\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:281 +msgid "The result of an inner join of `survey_sub` and `species_sub` is a new DataFrame\n" +"that contains the combined set of columns from `survey_sub` and `species_sub`. It\n" +"*only* contains rows that have two-letter species codes that are the same in\n" +"both the `survey_sub` and `species_sub` DataFrames. In other words, if a row in\n" +"`survey_sub` has a value of `species_id` that does *not* appear in the `species_id`\n" +"column of `species`, it will not be included in the DataFrame returned by an\n" +"inner join. Similarly, if a row in `species_sub` has a value of `species_id`\n" +"that does *not* appear in the `species_id` column of `survey_sub`, that row will not\n" +"be included in the DataFrame returned by an inner join." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:291 +msgid "The two DataFrames that we want to join are passed to the `merge` function using\n" +"the `left` and `right` argument. The `left_on='species'` argument tells `merge`\n" +"to use the `species_id` column as the join key from `survey_sub` (the `left`\n" +"DataFrame). Similarly , the `right_on='species_id'` argument tells `merge` to\n" +"use the `species_id` column as the join key from `species_sub` (the `right`\n" +"DataFrame). For inner joins, the order of the `left` and `right` arguments does\n" +"not matter." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:299 +msgid "The result `merged_inner` DataFrame contains all of the columns from `survey_sub`\n" +"(record id, month, day, etc.) as well as all the columns from `species_sub`\n" +"(species_id, genus, species, and taxa)." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:303 +msgid "Notice that `merged_inner` has fewer rows than `survey_sub`. This is an\n" +"indication that there were rows in `surveys_df` with value(s) for `species_id` that\n" +"do not exist as value(s) for `species_id` in `species_df`." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:307 +# header +msgid "## Left joins" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:309 +msgid "What if we want to add information from `species_sub` to `survey_sub` without\n" +"losing any of the information from `survey_sub`? In this case, we use a different\n" +"type of join called a \"left outer join\", or a \"left join\"." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:313 +msgid "Like an inner join, a left join uses join keys to combine two DataFrames. Unlike\n" +"an inner join, a left join will return *all* of the rows from the `left`\n" +"DataFrame, even those rows whose join key(s) do not have values in the `right`\n" +"DataFrame. Rows in the `left` DataFrame that are missing values for the join\n" +"key(s) in the `right` DataFrame will simply have null (i.e., NaN or None) values\n" +"for those columns in the resulting joined DataFrame." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:320 +msgid "Note: a left join will still discard rows from the `right` DataFrame that do not\n" +"have values for the join key(s) in the `left` DataFrame." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:323 +msgid "![Left Join](../fig/left-join.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:325 +msgid "A left join is performed in pandas by calling the same `merge` function used for\n" +"inner join, but using the `how='left'` argument:" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:328 +# code block +msgid "~~~\n" +"merged_left = pd.merge(left=survey_sub,right=species_sub, how='left', left_on='species_id', right_on='species_id')\n" +"merged_left\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:332 +msgid "{: .language-python}\n" +"~~~\n" +" record_id month day year plot_id species_id sex hindfoot_length \\\n" +"0 1 7 16 1977 2 NL M 32\n" +"1 2 7 16 1977 3 NL M 33\n" +"2 3 7 16 1977 2 DM F 37\n" +"3 4 7 16 1977 7 DM M 36\n" +"4 5 7 16 1977 3 DM M 35\n" +"5 6 7 16 1977 1 PF M 14\n" +"6 7 7 16 1977 2 PE F NaN\n" +"7 8 7 16 1977 1 DM M 37\n" +"8 9 7 16 1977 1 DM F 34\n" +"9 10 7 16 1977 6 PF F 20" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:346 +msgid " weight genus species taxa\n" +"0 NaN Neotoma albigula Rodent\n" +"1 NaN Neotoma albigula Rodent\n" +"2 NaN Dipodomys merriami Rodent\n" +"3 NaN Dipodomys merriami Rodent\n" +"4 NaN Dipodomys merriami Rodent\n" +"5 NaN NaN NaN NaN\n" +"6 NaN Peromyscus eremicus Rodent\n" +"7 NaN Dipodomys merriami Rodent\n" +"8 NaN Dipodomys merriami Rodent\n" +"9 NaN NaN NaN NaN\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:360 +msgid "The result DataFrame from a left join (`merged_left`) looks very much like the\n" +"result DataFrame from an inner join (`merged_inner`) in terms of the columns it\n" +"contains. However, unlike `merged_inner`, `merged_left` contains the **same\n" +"number of rows** as the original `survey_sub` DataFrame. When we inspect\n" +"`merged_left`, we find there are rows where the information that should have\n" +"come from `species_sub` (i.e., `species_id`, `genus`, and `taxa`) is\n" +"missing (they contain NaN values):" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:368 +# code block +msgid "~~~\n" +"merged_left[ pd.isnull(merged_left.genus) ]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:371 +msgid "{: .language-python}\n" +"~~~\n" +" record_id month day year plot_id species_id sex hindfoot_length \\\n" +"5 6 7 16 1977 1 PF M 14\n" +"9 10 7 16 1977 6 PF F 20" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:377 +msgid " weight genus species taxa\n" +"5 NaN NaN NaN NaN\n" +"9 NaN NaN NaN NaN\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:383 +msgid "These rows are the ones where the value of `species_id` from `survey_sub` (in this\n" +"case, `PF`) does not occur in `species_sub`." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:387 +# header +msgid "## Other join types" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:389 +msgid "The pandas `merge` function supports two other join types:" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:391 +# unordered list +msgid "* Right (outer) join: Invoked by passing `how='right'` as an argument. Similar" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:392 +msgid " to a left join, except *all* rows from the `right` DataFrame are kept, while\n" +" rows from the `left` DataFrame without matching join key(s) values are\n" +" discarded.\n" +"* Full (outer) join: Invoked by passing `how='outer'` as an argument. This join\n" +" type returns the all pairwise combinations of rows from both DataFrames; i.e.,\n" +" the result DataFrame will `NaN` where data is missing in one of the dataframes. This join type is\n" +" very rarely used." +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:400 +# header +msgid "# Final Challenges" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:402 +# blockquote, which can be cascaded +msgid "> ## Challenge - Distributions" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:403 +# blockquote, which can be cascaded +msgid "> Create a new DataFrame by joining the contents of the `surveys.csv` and" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:404 +# blockquote, which can be cascaded +msgid "> `species.csv` tables. Then calculate and plot the distribution of:" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:405 +msgid ">\n" +"> 1. taxa by plot\n" +"> 2. taxa by sex by plot" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:410 +# blockquote, which can be cascaded +msgid "> ## Challenge - Diversity Index" +msgstr "" + +#: python-ecology-lesson/_episodes/05-merging-data.md:411 +msgid ">\n" +"> 1. In the data folder, there is a `plots.csv` file that contains information about the\n" +"> type associated with each plot. Use that data to summarize the number of\n" +"> plots by plot type.\n" +"> 2. Calculate a diversity index of your choice for control vs rodent exclosure\n" +"> plots. The index should consider both species abundance and number of\n" +"> species. You might choose to use the simple [biodiversity index described\n" +"> here](http://www.amnh.org/explore/curriculum-collections/biodiversity-counts/plant-ecology/how-to-calculate-a-biodiversity-index)\n" +"> which calculates diversity as:\n" +">\n" +"> the number of species in the plot / the total number of individuals in the plot = Biodiversity index." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:1 +# Front Matter +msgid "---\n" +"title: Data Workflows and Automation\n" +"teaching: 40\n" +"exercises: 50\n" +"questions:\n" +" - \"Can I automate operations in Python?\"\n" +" - \"What are functions and why should I use them?\"\n" +"objectives:\n" +" - \"Describe why for loops are used in Python.\"\n" +" - \"Employ for loops to automate data analysis.\"\n" +" - \"Write unique filenames in Python.\"\n" +" - \"Build reusable code in Python.\"\n" +" - \"Write functions using conditional statements (if, then, else).\"\n" +"keypoints:\n" +" - \"Loops help automate repetitive tasks over sets of items.\"\n" +" - \"Loops combined with functions provide a way to process data more efficiently than we could by hand.\"\n" +" - \"Conditional statements enable execution of different operations on different data.\"\n" +" - \"Functions enable code reuse.\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:21 +msgid "So far, we've used Python and the pandas library to explore and manipulate\n" +"individual datasets by hand, much like we would do in a spreadsheet. The beauty\n" +"of using a programming language like Python, though, comes from the ability to\n" +"automate data processing through the use of loops and functions." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:26 +# header +msgid "## For loops" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:28 +msgid "Loops allow us to repeat a workflow (or series of actions) a given number of\n" +"times or while some condition is true. We would use a loop to automatically\n" +"process data that's stored in multiple files (daily values with one file per\n" +"year, for example). Loops lighten our work load by performing repeated tasks\n" +"without our direct involvement and make it less likely that we'll introduce\n" +"errors by making mistakes while processing each file by hand." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:35 +msgid "Let's write a simple for loop that simulates what a kid might see during a\n" +"visit to the zoo:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:38 +# code block +msgid "~~~\n" +"animals = ['lion', 'tiger', 'crocodile', 'vulture', 'hippo']\n" +"print(animals)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:44 +# code block +msgid "~~~\n" +"['lion', 'tiger', 'crocodile', 'vulture', 'hippo']\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:49 +# code block +msgid "~~~\n" +"for creature in animals:\n" +" print(creature)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:55 +# code block +msgid "~~~\n" +"lion\n" +"tiger\n" +"crocodile\n" +"vulture\n" +"hippo\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:64 +msgid "The line defining the loop must start with `for` and end with a colon, and the\n" +"body of the loop must be indented." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:67 +msgid "In this example, `creature` is the loop variable that takes the value of the next\n" +"entry in `animals` every time the loop goes around. We can call the loop variable\n" +"anything we like. After the loop finishes, the loop variable will still exist\n" +"and will have the value of the last entry in the collection:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:72 +# code block +msgid "~~~\n" +"animals = ['lion', 'tiger', 'crocodile', 'vulture', 'hippo']\n" +"for creature in animals:\n" +" pass\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:79 +# code block +msgid "~~~\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:83 +# code block +msgid "~~~\n" +"print('The loop variable is now: ' + creature)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:88 +# code block +msgid "~~~\n" +"The loop variable is now: hippo\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:93 +msgid "We are not asking Python to print the value of the loop variable anymore, but\n" +"the for loop still runs and the value of `creature` changes on each pass through\n" +"the loop. The statement `pass` in the body of the loop just means \"do nothing\"." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:97 +# blockquote, which can be cascaded +msgid "> ## Challenge - Loops" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:98 +msgid ">\n" +"> 1. What happens if we don't include the `pass` statement?\n" +">\n" +"> 2. Rewrite the loop so that the animals are separated by commas, not new lines\n" +"> (Hint: You can concatenate strings using a plus sign. For example,\n" +"> `print(string1 + string2)` outputs 'string1string2')." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:106 +# header +msgid "## Automating data processing using For Loops" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:108 +msgid "The file we've been using so far, `surveys.csv`, contains 25 years of data and is\n" +"very large. We would like to separate the data for each year into a separate\n" +"file." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:112 +msgid "Let's start by making a new directory inside the folder `data` to store all of\n" +"these files using the module `os`:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:115 +# code block +msgid "~~~\n" +"import os\n" +"\n" +"os.mkdir('data/yearly_files')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:122 +msgid "The command `os.mkdir` is equivalent to `mkdir` in the shell. Just so we are\n" +"sure, we can check that the new directory was created within the `data` folder:\n" +"~~~\n" +"os.listdir('data')\n" +"~~~\n" +"{: .language-python}\n" +"~~~\n" +"['plots.csv',\n" +" 'portal_mammals.sqlite',\n" +" 'species.csv',\n" +" 'survey2001.csv',\n" +" 'survey2002.csv',\n" +" 'surveys.csv',\n" +" 'surveys2002_temp.csv',\n" +" 'yearly_files']\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:140 +msgid "The command `os.listdir` is equivalent to `ls` in the shell." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:142 +msgid "In previous lessons, we saw how to use the library pandas to load the species\n" +"data into memory as a DataFrame, how to select a subset of the data using some\n" +"criteria, and how to write the DataFrame into a CSV file. Let's write a script\n" +"that performs those three steps in sequence for the year 2002:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:147 +# code block +msgid "~~~\n" +"import pandas as pd\n" +"\n" +"# Load the data into a DataFrame\n" +"surveys_df = pd.read_csv('data/surveys.csv')\n" +"\n" +"# Select only data for the year 2002\n" +"surveys2002 = surveys_df[surveys_df.year == 2002]\n" +"\n" +"# Write the new DataFrame to a CSV file\n" +"surveys2002.to_csv('data/yearly_files/surveys2002.csv')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:161 +msgid "To create yearly data files, we could repeat the last two commands over and\n" +"over, once for each year of data. Repeating code is neither elegant nor\n" +"practical, and is very likely to introduce errors into your code. We want to\n" +"turn what we've just written into a loop that repeats the last two commands for\n" +"every year in the dataset." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:167 +msgid "Let's start by writing a loop that simply prints the names of the files we want\n" +"to create - the dataset we are using covers 1977 through 2002, and we'll create\n" +"a separate file for each of those years. Listing the filenames is a good way to\n" +"confirm that the loop is behaving as we expect." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:172 +msgid "We have seen that we can loop over a list of items, so we need a list of years\n" +"to loop over. We can get the years in our DataFrame with:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:175 +# code block +msgid "~~~\n" +"surveys_df['year']\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:178 +msgid "{: .language-python}\n" +"~~~\n" +"0 1977\n" +"1 1977\n" +"2 1977\n" +"3 1977\n" +" ...\n" +"35545 2002\n" +"35546 2002\n" +"35547 2002\n" +"35548 2002\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:192 +msgid "but we want only unique years, which we can get using the `unique` method\n" +"which we have already seen." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:195 +# code block +msgid "~~~\n" +"surveys_df['year'].unique()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:198 +msgid "{: .language-python}\n" +"~~~\n" +"array([1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987,\n" +" 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,\n" +" 1999, 2000, 2001, 2002], dtype=int64)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:206 +msgid "Putting this into our for loop we get" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:208 +# code block +msgid "~~~\n" +"for year in surveys_df['year'].unique():\n" +" filename='data/yearly_files/surveys' + str(year) + '.csv'\n" +" print(filename)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:213 +msgid "{: .language-python}\n" +"~~~\n" +"data/yearly_files/surveys1977.csv\n" +"data/yearly_files/surveys1978.csv\n" +"data/yearly_files/surveys1979.csv\n" +"data/yearly_files/surveys1980.csv\n" +"data/yearly_files/surveys1981.csv\n" +"data/yearly_files/surveys1982.csv\n" +"data/yearly_files/surveys1983.csv\n" +"data/yearly_files/surveys1984.csv\n" +"data/yearly_files/surveys1985.csv\n" +"data/yearly_files/surveys1986.csv\n" +"data/yearly_files/surveys1987.csv\n" +"data/yearly_files/surveys1988.csv\n" +"data/yearly_files/surveys1989.csv\n" +"data/yearly_files/surveys1990.csv\n" +"data/yearly_files/surveys1991.csv\n" +"data/yearly_files/surveys1992.csv\n" +"data/yearly_files/surveys1993.csv\n" +"data/yearly_files/surveys1994.csv\n" +"data/yearly_files/surveys1995.csv\n" +"data/yearly_files/surveys1996.csv\n" +"data/yearly_files/surveys1997.csv\n" +"data/yearly_files/surveys1998.csv\n" +"data/yearly_files/surveys1999.csv\n" +"data/yearly_files/surveys2000.csv\n" +"data/yearly_files/surveys2001.csv\n" +"data/yearly_files/surveys2002.csv\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:244 +msgid "We can now add the rest of the steps we need to create separate text files:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:246 +# code block +msgid "~~~\n" +"# Load the data into a DataFrame\n" +"surveys_df = pd.read_csv('data/surveys.csv')\n" +"\n" +"for year in surveys_df['year'].unique():\n" +"\n" +" # Select data for the year\n" +" surveys_year = surveys_df[surveys_df.year == year]\n" +"\n" +" # Write the new DataFrame to a CSV file\n" +" filename = 'data/yearly_files/surveys' + str(year) + '.csv'\n" +" surveys_year.to_csv(filename)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:261 +msgid "Look inside the `yearly_files` directory and check a couple of the files you\n" +"just created to confirm that everything worked as expected." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:264 +# header +msgid "## Writing Unique FileNames" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:266 +msgid "Notice that the code above created a unique filename for each year." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:268 +# code block +msgid "~~~\n" +"filename = 'data/yearly_files/surveys' + str(year) + '.csv'\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:273 +msgid "Let's break down the parts of this name:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:275 +# unordered list +msgid "* The first part is simply some text that specifies the directory to store our" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:276 +msgid " data file in (data/yearly_files/) and the first part of the file name\n" +" (surveys): `'data/yearly_files/surveys'`\n" +"* We can concatenate this with the value of a variable, in this case `year` by\n" +" using the plus `+` sign and the variable we want to add to the file name: `+\n" +" str(year)`\n" +"* Then we add the file extension as another text string: `+ '.csv'`" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:283 +msgid "Notice that we use single quotes to add text strings. The variable is not\n" +"surrounded by quotes. This code produces the string\n" +"`data/yearly_files/surveys2002.csv` which contains the path to the new filename\n" +"AND the file name itself." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:288 +# blockquote, which can be cascaded +msgid "> ## Challenge - Modifying loops" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:289 +msgid ">\n" +"> 1. Some of the surveys you saved are missing data (they have null values that\n" +"> show up as NaN - Not A Number - in the DataFrames and do not show up in the text\n" +"> files). Modify the for loop so that the entries with null values are not\n" +"> included in the yearly files.\n" +">\n" +"> 2. Let's say you only want to look at data from a given multiple of years. How would you modify your loop in order to generate a data file for only every 5th year, starting from 1977?\n" +">\n" +"> 3. Instead of splitting out the data by years, a colleague wants to do analyses each species separately. How would you write a unique CSV file for each species?" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:300 +# header +msgid "## Building reusable and modular code with functions" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:302 +msgid "Suppose that separating large data files into individual yearly files is a task\n" +"that we frequently have to perform. We could write a **for loop** like the one above\n" +"every time we needed to do it but that would be time consuming and error prone.\n" +"A more elegant solution would be to create a reusable tool that performs this\n" +"task with minimum input from the user. To do this, we are going to turn the code\n" +"we've already written into a function." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:309 +msgid "Functions are reusable, self-contained pieces of code that are called with a\n" +"single command. They can be designed to accept arguments as input and return\n" +"values, but they don't need to do either. Variables declared inside functions\n" +"only exist while the function is running and if a variable within the function\n" +"(a local variable) has the same name as a variable somewhere else in the code,\n" +"the local variable hides but doesn't overwrite the other." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:316 +msgid "Every method used in Python (for example, `print`) is a function, and the\n" +"libraries we import (say, `pandas`) are a collection of functions. We will only\n" +"use functions that are housed within the same code that uses them, but it's also\n" +"easy to write functions that can be used by different programs." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:321 +msgid "Functions are declared following this general structure:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:323 +# code block +msgid "~~~\n" +"def this_is_the_function_name(input_argument1, input_argument2):\n" +"\n" +" # The body of the function is indented\n" +" # This function prints the two arguments to screen\n" +" print('The function arguments are:', input_argument1, input_argument2, '(this is done inside the function!)')\n" +"\n" +" # And returns their product\n" +" return input_argument1 * input_argument2\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:335 +msgid "The function declaration starts with the word `def`, followed by the function\n" +"name and any arguments in parenthesis, and ends in a colon. The body of the\n" +"function is indented just like loops are. If the function returns something when\n" +"it is called, it includes a return statement at the end." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:340 +msgid "This is how we call the function:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:342 +# code block +msgid "~~~\n" +"product_of_inputs = this_is_the_function_name(2,5)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:347 +# code block +msgid "~~~\n" +"The function arguments are: 2 5 (this is done inside the function!)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:352 +# code block +msgid "~~~\n" +"print('Their product is:', product_of_inputs, '(this is done outside the function!)')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:357 +# code block +msgid "~~~\n" +"Their product is: 10 (this is done outside the function!)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:362 +# blockquote, which can be cascaded +msgid "> ## Challenge - Functions" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:363 +msgid ">\n" +"> 1. Change the values of the arguments in the function and check its output\n" +"> 2. Try calling the function by giving it the wrong number of arguments (not 2)\n" +"> or not assigning the function call to a variable (no `product_of_inputs =`)\n" +"> 3. Declare a variable inside the function and test to see where it exists (Hint:\n" +"> can you print it from outside the function?)\n" +"> 4. Explore what happens when a variable both inside and outside the function\n" +"> have the same name. What happens to the global variable when you change the\n" +"> value of the local variable?" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:374 +msgid "We can now turn our code for saving yearly data files into a function. There are\n" +"many different \"chunks\" of this code that we can turn into functions, and we can\n" +"even create functions that call other functions inside them. Let's first write a\n" +"function that separates data for just one year and saves that data to a file:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:379 +# code block +msgid "~~~\n" +"def one_year_csv_writer(this_year, all_data):\n" +" \"\"\"\n" +" Writes a csv file for data from a given year.\n" +"\n" +" this_year --- year for which data is extracted\n" +" all_data --- DataFrame with multi-year data\n" +" \"\"\"\n" +"\n" +" # Select data for the year\n" +" surveys_year = all_data[all_data.year == this_year]\n" +"\n" +" # Write the new DataFrame to a csv file\n" +" filename = 'data/yearly_files/function_surveys' + str(this_year) + '.csv'\n" +" surveys_year.to_csv(filename)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:397 +msgid "The text between the two sets of triple double quotes is called a docstring and\n" +"contains the documentation for the function. It does nothing when the function\n" +"is running and is therefore not necessary, but it is good practice to include\n" +"docstrings as a reminder of what the code does. Docstrings in functions also\n" +"become part of their 'official' documentation:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:403 +# code block +msgid "~~~\n" +"one_year_csv_writer?\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:408 +# code block +msgid "~~~\n" +"one_year_csv_writer(2002, surveys_df)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:413 +msgid "We changed the root of the name of the CSV file so we can distinguish it from\n" +"the one we wrote before. Check the `yearly_files` directory for the file. Did it\n" +"do what you expect?" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:417 +msgid "What we really want to do, though, is create files for multiple years without\n" +"having to request them one by one. Let's write another function that replaces\n" +"the entire For loop by simply looping through a sequence of years and repeatedly\n" +"calling the function we just wrote, `one_year_csv_writer`:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:423 +# code block +msgid "~~~\n" +"def yearly_data_csv_writer(start_year, end_year, all_data):\n" +" \"\"\"\n" +" Writes separate CSV files for each year of data.\n" +"\n" +" start_year --- the first year of data we want\n" +" end_year --- the last year of data we want\n" +" all_data --- DataFrame with multi-year data\n" +" \"\"\"\n" +"\n" +" # \"end_year\" is the last year of data we want to pull, so we loop to end_year+1\n" +" for year in range(start_year, end_year+1):\n" +" one_year_csv_writer(year, all_data)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:439 +msgid "Because people will naturally expect that the end year for the files is the last\n" +"year with data, the for loop inside the function ends at `end_year + 1`. By\n" +"writing the entire loop into a function, we've made a reusable tool for whenever\n" +"we need to break a large data file into yearly files. Because we can specify the\n" +"first and last year for which we want files, we can even use this function to\n" +"create files for a subset of the years available. This is how we call this\n" +"function:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:447 +# code block +msgid "~~~\n" +"# Load the data into a DataFrame\n" +"surveys_df = pd.read_csv('data/surveys.csv')\n" +"\n" +"# Create CSV files\n" +"yearly_data_csv_writer(1977, 2002, surveys_df)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:456 +msgid "BEWARE! If you are using IPython Notebooks and you modify a function, you MUST\n" +"re-run that cell in order for the changed function to be available to the rest\n" +"of the code. Nothing will visibly happen when you do this, though, because\n" +"simply defining a function without *calling* it doesn't produce an output. Any\n" +"cells that use the now-changed functions will also have to be re-run for their\n" +"output to change." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:463 +# blockquote, which can be cascaded +msgid "> ## Challenge- More functions" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:464 +msgid ">\n" +"> 1. Add two arguments to the functions we wrote that take the path of the\n" +"> directory where the files will be written and the root of the file name.\n" +"> Create a new set of files with a different name in a different directory.\n" +"> 2. How could you use the function `yearly_data_csv_writer` to create a CSV file\n" +"> for only one year? (Hint: think about the syntax for `range`)\n" +"> 3. Make the functions return a list of the files they have written. There are\n" +"> many ways you can do this (and you should try them all!): either of the\n" +"> functions can print to screen, either can use a return statement to give back\n" +"> numbers or strings to their function call, or you can use some combination of\n" +"> the two. You could also try using the `os` library to list the contents of\n" +"> directories.\n" +"> 4. Explore what happens when variables are declared inside each of the functions\n" +"> versus in the main (non-indented) body of your code. What is the scope of the\n" +"> variables (where are they visible)? What happens when they have the same name\n" +"> but are given different values?" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:482 +msgid "The functions we wrote demand that we give them a value for every argument.\n" +"Ideally, we would like these functions to be as flexible and independent as\n" +"possible. Let's modify the function `yearly_data_csv_writer` so that the\n" +"`start_year` and `end_year` default to the full range of the data if they are\n" +"not supplied by the user. Arguments can be given default values with an equal\n" +"sign in the function declaration. Any arguments in the function without default\n" +"values (here, `all_data`) is a required argument and MUST come before the\n" +"argument with default values (which are optional in the function call)." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:491 +# code block +msgid "~~~\n" +"def yearly_data_arg_test(all_data, start_year = 1977, end_year = 2002):\n" +" \"\"\"\n" +" Modified from yearly_data_csv_writer to test default argument values!\n" +"\n" +" start_year --- the first year of data we want --- default: 1977\n" +" end_year --- the last year of data we want --- default: 2002\n" +" all_data --- DataFrame with multi-year data\n" +" \"\"\"\n" +"\n" +" return start_year, end_year\n" +"\n" +"\n" +"start,end = yearly_data_arg_test (surveys_df, 1988, 1993)\n" +"print('Both optional arguments:\\t', start, end)\n" +"\n" +"start,end = yearly_data_arg_test (surveys_df)\n" +"print('Default values:\\t\\t\\t', start, end)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:512 +# code block +msgid "~~~\n" +"Both optional arguments: 1988 1993\n" +"Default values: 1977 2002\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:518 +msgid "The \"\\t\" in the `print` statements are tabs, used to make the text align and be\n" +"easier to read." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:521 +msgid "But what if our dataset doesn't start in 1977 and end in 2002? We can modify the\n" +"function so that it looks for the start and end years in the dataset if those\n" +"dates are not provided:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:525 +# code block +msgid "~~~\n" +"def yearly_data_arg_test(all_data, start_year = None, end_year = None):\n" +" \"\"\"\n" +" Modified from yearly_data_csv_writer to test default argument values!\n" +"\n" +" start_year --- the first year of data we want --- default: None - check all_data\n" +" end_year --- the last year of data we want --- default: None - check all_data\n" +" all_data --- DataFrame with multi-year data\n" +" \"\"\"\n" +"\n" +" if start_year is None:\n" +" start_year = min(all_data.year)\n" +" if end_year is None:\n" +" end_year = max(all_data.year)\n" +"\n" +" return start_year, end_year\n" +"\n" +"\n" +"start,end = yearly_data_arg_test (surveys_df, 1988, 1993)\n" +"print('Both optional arguments:\\t', start, end)\n" +"\n" +"start,end = yearly_data_arg_test (surveys_df)\n" +"print('Default values:\\t\\t\\t', start, end)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:549 +msgid "{: .language-python}\n" +"~~~\n" +"Both optional arguments: 1988 1993\n" +"Default values: 1977 2002\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:556 +msgid "The default values of the `start_year` and `end_year` arguments in the function\n" +"`yearly_data_arg_test` are now `None`. This is a build-it constant in Python\n" +"that indicates the absence of a value - essentially, that the variable exists in\n" +"the namespace of the function (the directory of variable names) but that it\n" +"doesn't correspond to any existing object." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:562 +# blockquote, which can be cascaded +msgid "> ## Challenge - Variables" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:563 +msgid ">\n" +"> 1. What type of object corresponds to a variable declared as `None`? (Hint:\n" +"> create a variable set to `None` and use the function `type()`)\n" +">\n" +"> 2. Compare the behavior of the function `yearly_data_arg_test` when the\n" +"> arguments have `None` as a default and when they do not have default values.\n" +">\n" +"> 3. What happens if you only include a value for `start_year` in the function\n" +"> call? Can you write the function call with only a value for `end_year`? (Hint:\n" +"> think about how the function must be assigning values to each of the arguments -\n" +"> this is related to the need to put the arguments without default values before\n" +"> those with default values in the function definition!)" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:577 +# header +msgid "## If Statements" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:579 +msgid "The body of the test function now has two conditionals (if statements) that\n" +"check the values of `start_year` and `end_year`. If statements execute a segment\n" +"of code when some condition is met. They commonly look something like this:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:583 +# code block +msgid "~~~\n" +"a = 5\n" +"\n" +"if a<0: # Meets first condition?\n" +"\n" +" # if a IS less than zero\n" +" print('a is a negative number')\n" +"\n" +"elif a>0: # Did not meet first condition. meets second condition?\n" +"\n" +" # if a ISN'T less than zero and IS more than zero\n" +" print('a is a positive number')\n" +"\n" +"else: # Met neither condition\n" +"\n" +" # if a ISN'T less than zero and ISN'T more than zero\n" +" print('a must be zero!')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:603 +msgid "Which would return:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:605 +# code block +msgid "~~~\n" +"a is a positive number\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:610 +msgid "Change the value of `a` to see how this function works. The statement `elif`\n" +"means \"else if\", and all of the conditional statements must end in a colon." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:613 +msgid "The if statements in the function `yearly_data_arg_test` check whether there is an\n" +"object associated with the variable names `start_year` and `end_year`. If those\n" +"variables are `None`, the if statements return the boolean `True` and execute whatever\n" +"is in their body. On the other hand, if the variable names are associated with\n" +"some value (they got a number in the function call), the if statements return `False`\n" +"and do not execute. The opposite conditional statements, which would return\n" +"`True` if the variables were associated with objects (if they had received value\n" +"in the function call), would be `if start_year` and `if end_year`." +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:622 +msgid "As we've written it so far, the function `yearly_data_arg_test` associates\n" +"values in the function call with arguments in the function definition just based\n" +"in their order. If the function gets only two values in the function call, the\n" +"first one will be associated with `all_data` and the second with `start_year`,\n" +"regardless of what we intended them to be. We can get around this problem by\n" +"calling the function using keyword arguments, where each of the arguments in the\n" +"function definition is associated with a keyword and the function call passes\n" +"values to the function using these keywords:" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:631 +# code block +msgid "~~~\n" +"start,end = yearly_data_arg_test (surveys_df)\n" +"print('Default values:\\t\\t\\t', start, end)\n" +"\n" +"start,end = yearly_data_arg_test (surveys_df, 1988, 1993)\n" +"print('No keywords:\\t\\t\\t', start, end)\n" +"\n" +"start,end = yearly_data_arg_test (surveys_df, start_year = 1988, end_year = 1993)\n" +"print('Both keywords, in order:\\t', start, end)\n" +"\n" +"start,end = yearly_data_arg_test (surveys_df, end_year = 1993, start_year = 1988)\n" +"print('Both keywords, flipped:\\t\\t', start, end)\n" +"\n" +"start,end = yearly_data_arg_test (surveys_df, start_year = 1988)\n" +"print('One keyword, default end:\\t', start, end)\n" +"\n" +"start,end = yearly_data_arg_test (surveys_df, end_year = 1993)\n" +"print('One keyword, default start:\\t', start, end)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:650 +msgid "{: .language-python}\n" +"~~~\n" +"Default values: 1977 2002\n" +"No keywords: 1988 1993\n" +"Both keywords, in order: 1988 1993\n" +"Both keywords, flipped: 1988 1993\n" +"One keyword, default end: 1988 2002\n" +"One keyword, default start: 1977 1993\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:661 +# blockquote, which can be cascaded +msgid "> ## Challenge - Modifying functions" +msgstr "" + +#: python-ecology-lesson/_episodes/06-loops-and-functions.md:662 +msgid ">\n" +"> 1. Rewrite the `one_year_csv_writer` and `yearly_data_csv_writer` functions to\n" +"> have keyword arguments with default values\n" +">\n" +"> 2. Modify the functions so that they don't create yearly files if there is no\n" +"> data for a given year and display an alert to the user (Hint: use conditional\n" +"> statements to do this. For an extra challenge, use `try`\n" +"> statements!)\n" +">\n" +"> 3. The code below checks to see whether a directory exists and creates one if it\n" +"> doesn't. Add some code to your function that writes out the CSV files, to check\n" +"> for a directory to write to.\n" +">\n" +"> ~~~\n" +">if 'dir_name_here' in os.listdir('.'):\n" +"> print('Processed directory exists')\n" +">else:\n" +"> os.mkdir('dir_name_here')\n" +"> print('Processed directory created')\n" +"> ~~~\n" +"> {: .language-python }\n" +">\n" +"> 4. The code that you have written so far to loop through the years is good,\n" +"> however it is not necessarily reproducible with different datasets.\n" +"> For instance, what happens to the code if we have additional years of data\n" +"> in our CSV files? Using the tools that you learned in the previous activities,\n" +"> make a list of all years represented in the data. Then create a loop to process\n" +"> your data, that begins at the earliest year and ends at the latest year using\n" +"> that list.\n" +">\n" +"> HINT: you can create a loop with a list as follows: `for years in year_list:`" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:1 +# Front Matter +msgid "---\n" +"title: Making Plots With plotnine\n" +"teaching: 40\n" +"exercises: 50\n" +"questions:\n" +" - \"How can I visualize data in Python?\"\n" +" - \"What is 'grammar of graphics'?\"\n" +"objectives:\n" +" - \"Create a `plotnine` object.\"\n" +" - \"Set universal plot settings.\"\n" +" - \"Modify an existing plotnine object.\"\n" +" - \"Change the aesthetics of a plot such as color.\"\n" +" - \"Edit the axis labels.\"\n" +" - \"Build complex plots using a step-by-step approach.\"\n" +" - \"Create scatter plots, box plots, and time series plots.\"\n" +" - \"Use the facet_wrap and facet_grid commands to create a collection of plots splitting the data by a factor variable.\"\n" +" - \"Create customized plot styles to meet their needs.\"\n" +"keypoints:\n" +" - \"The `data`, `aes` variables and a `geometry` are the main elements of a plotnine graph\"\n" +" - \"With the `+` operator, additional `scale_*`, `theme_*`, `xlab/ylab` and `facet_*` elements are added\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:23 +# header +msgid "## Disclaimer" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:25 +msgid "Python has powerful built-in plotting capabilities such as `matplotlib`, but for\n" +"this episode, we will be using the [`plotnine`][plotnine]\n" +"package, which facilitates the creation of highly-informative plots of\n" +"structured data based on the R implementation of [`ggplot2`][ggplot2]\n" +"and [The Grammar of Graphics][grammar-of-graphics]\n" +"by Leland Wilkinson. The `plotnine`\n" +"package is built on top of Matplotlib and interacts well with Pandas." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:33 +msgid "Just as with the other packages, `plotnine` need to be imported. It is good\n" +"practice to not just load an entire package such as `from plotnine import *`,\n" +"but to use an abbreviation as we used `pd` for Pandas:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:37 +# code block +msgid "~~~\n" +"%matplotlib inline\n" +"import plotnine as p9\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:43 +msgid "From now on, the functions of `plotnine` are available using `p9.`. For the\n" +"exercise, we will use the `surveys.csv` data set, with the `NA` values removed" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:46 +# code block +msgid "~~~\n" +"import pandas as pd\n" +"\n" +"surveys_complete = pd.read_csv('data/surveys.csv')\n" +"surveys_complete = surveys_complete.dropna()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:54 +# header +msgid "## Plotting with plotnine" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:56 +msgid "The `plotnine` package (cfr. other packages conform The Grammar of Graphics) supports the creation of complex plots from data in a\n" +"dataframe. It uses default settings, which help creating publication quality\n" +"plots with a minimal amount of settings and tweaking." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:60 +msgid "`plotnine` graphics are built step by step by adding new elementsadding\n" +"different elements on top of each other using the `+` operator. Putting the\n" +"individual steps together in brackets `()` provides Python-compatible syntax." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:64 +msgid "To build a `plotnine` graphic we need to:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:66 +# unordered list +msgid "- Bind the plot to a specific data frame using the `data` argument:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:68 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete))\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:71 +msgid "{: .language-python}\n" +"As we have not defined anything else, just an empty figure is available and\n" +"presented." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:75 +msgid "As we have not defined anything else, just an empty figure is available and\n" +"presented." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:78 +# unordered list +msgid "- Define aesthetics (`aes`), by **selecting variables** used in the plot and" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:79 +msgid "`mapping` them to a presentation such as plotting size, shape color, etc. You\n" +"can interpret this as: *which** of the variables will influence the plotted\n" +"objects/geometries:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:83 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight', y='hindfoot_length')))\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:89 +msgid "The most important aes mappings are: `x`, `y`, `alpha`, `color`, `colour`,\n" +"`fill`, `linetype`, `shape`, `size` and `stroke`." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:92 +# unordered list +msgid "- Still no specific data is plotted, as we have to define what kind of geometry" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:93 +msgid "will be used for the plot. The most straightforward is probably using points.\n" +"Points is one of the `geoms` options, the graphical representation of the data\n" +"in the plot. Others are lines, bars,... To add a geom to the plot use `+`\n" +"operator:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:98 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:157 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight', y='hindfoot_length'))\n" +" + p9.geom_point()\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:106 +msgid "The `+` in the `plotnine` package is particularly useful because it allows you\n" +"to modify existing `plotnine` objects. This means you can easily set up plot\n" +"*templates* and conveniently explore different types of plots, so the above\n" +"plot can also be generated with code like this:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:112 +# code block +msgid "~~~\n" +"# Create\n" +"surveys_plot = p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight', y='hindfoot_length'))\n" +"\n" +"# Draw the plot\n" +"surveys_plot + p9.geom_point()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:122 +msgid "![png](../fig/06_first_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:124 +# blockquote, which can be cascaded +msgid "> ## Challenge - bar chart" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:125 +# blockquote, which can be cascaded +msgid "> Working on the `surveys_complete` data set, use the `plot-id` column to" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:126 +# blockquote, which can be cascaded +msgid "> create a `bar`-plot that counts the number of records for each plot. (Check" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:127 +# blockquote, which can be cascaded +msgid "> the documentation of the bar geometry to handle the counts)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:128 +msgid ">\n" +"> > ## Answers\n" +"> >\n" +"> > ~~~\n" +"> > (p9.ggplot(data=surveys_complete,\n" +"> > mapping=p9.aes(x='plot_id'))\n" +"> > + p9.geom_bar()\n" +"> > )\n" +"> > ~~~\n" +"> > {: .language-python}\n" +"> >\n" +"> > ![png](../fig/06_challenge_bar.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:140 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:275 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:344 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:485 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:505 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:326 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:356 +# SC/DC Template label +msgid "> {: .solution}" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:143 +msgid "Notes:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:145 +# unordered list +msgid "- Anything you put in the `ggplot()` function can be seen by any geom layers" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:146 +msgid "that you add (i.e., these are universal plot settings). This includes the `x`\n" +"and `y` axis you set up in `aes()`.\n" +"- You can also specify aesthetics for a given `geom` independently of the\n" +"aesthetics defined globally in the `ggplot()` function." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:151 +# header +msgid "## Building your plots iteratively" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:153 +msgid "Building plots with `plotnine` is typically an iterative process. We start by\n" +"defining the dataset we'll use, lay the axes, and choose a geom. Hence, the\n" +"`data`, `aes` and `geom-*` are the elementary elements of any graph:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:165 +msgid "Then, we start modifying this plot to extract more information from it. For\n" +"instance, we can add transparency (alpha) to avoid overplotting:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:169 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight', y='hindfoot_length'))\n" +" + p9.geom_point(alpha=0.1)\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:177 +msgid "![png](../fig/06_alpha_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:179 +msgid "We can also add colors for all the points" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:182 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight', y='hindfoot_length'))\n" +" + p9.geom_point(alpha=0.1, color='blue')\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:190 +msgid "![png](../fig/06_blue_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:192 +msgid "Or to color each species in the plot differently, map the `species_id` column\n" +"to the color aesthetic:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:195 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:407 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight',\n" +" y='hindfoot_length',\n" +" color='species_id'))\n" +" + p9.geom_point(alpha=0.1)\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:205 +msgid "![png](../fig/06_color_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:207 +msgid "Apart from the adaptations of the arguments and settings of the `data`, `aes`\n" +"and `geom-*` elements, additional elements can be added as well, using the `+`\n" +"operator:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:211 +# unordered list +msgid "- Changing the labels:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:213 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight', y='hindfoot_length', color='species_id'))\n" +" + p9.geom_point(alpha=0.1)\n" +" + p9.xlab(\"Weight (g)\")\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:222 +msgid "![png](../fig/06_color_label_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:224 +# unordered list +msgid "- Defining scale for colors, axes,... For example, a log-version of the x-axis" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:225 +msgid "could support the interpretation of the lower numbers:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:227 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight', y='hindfoot_length', color='species_id'))\n" +" + p9.geom_point(alpha=0.1)\n" +" + p9.xlab(\"Weight (g)\")\n" +" + p9.scale_x_log10()\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:237 +msgid "![png](../fig/06_log_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:239 +# unordered list +msgid "- Changing the theme (`theme_*`) or some specific theming (`theme`) elements." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:240 +msgid "Usually plots with white background look more readable when printed. We can\n" +"set the background to white using the function `theme_bw()`." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:243 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight', y='hindfoot_length', color='species_id'))\n" +" + p9.geom_point(alpha=0.1)\n" +" + p9.xlab(\"Weight (g)\")\n" +" + p9.scale_x_log10()\n" +" + p9.theme_bw()\n" +" + p9.theme(text=p9.element_text(size=16))\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:255 +msgid "![png](../fig/06_white_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:257 +# blockquote, which can be cascaded +msgid "> ## Challenge - Bar plot adaptations" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:258 +# blockquote, which can be cascaded +msgid "> Adapt the bar plot of the previous exercise by mapping the `sex` variable to" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:259 +# blockquote, which can be cascaded +msgid "> the color fill of the bar chart. Change the `scale` of the color fill by" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:260 +# blockquote, which can be cascaded +msgid "> providing the colors `blue` and `orange` manually" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:261 +# blockquote, which can be cascaded +msgid "> (see [API reference][plotnine-api] to find the appropriate function)." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:262 +msgid ">\n" +"> > ## Answers\n" +"> >\n" +"> > ~~~\n" +"> > (p9.ggplot(data=surveys_complete,\n" +"> > mapping=p9.aes(x='plot_id',\n" +"> > fill='sex'))\n" +"> > + p9.geom_bar()\n" +"> > + p9.scale_fill_manual([\"blue\", \"orange\"])\n" +"> > )\n" +"> > ~~~\n" +"> > {: .language-python}\n" +"> > ![png](../fig/06_challenge_color_bar.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:279 +# header +msgid "## Plotting distributions" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:281 +msgid "Visualizing distributions is a common task during data exploration and\n" +"analysis. To visualize the distribution of `weight` within each `species_id`\n" +"group, a boxplot can be used:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:285 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='species_id',\n" +" y='weight'))\n" +" + p9.geom_boxplot()\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:294 +msgid "![png](../fig/06_boxplot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:296 +msgid "By adding points of the individual observations to the boxplot, we can have a\n" +"better idea of the number of measurements and of their distribution:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:299 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='species_id',\n" +" y='weight'))\n" +" + p9.geom_jitter(alpha=0.2)\n" +" + p9.geom_boxplot(alpha=0.)\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:309 +msgid "![png](../fig/06_point_boxplot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:311 +# blockquote, which can be cascaded +msgid "> ## Challenge - distributions" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:312 +msgid ">\n" +"> Boxplots are useful summaries, but hide the *shape* of the distribution.\n" +"> For example, if there is a bimodal distribution, this would not be observed\n" +"> with a boxplot. An alternative to the boxplot is the violin plot (sometimes\n" +"> known as a beanplot), where the shape (of the density of points) is drawn.\n" +">\n" +"> In many types of data, it is important to consider the *scale* of the\n" +"> observations. For example, it may be worth changing the scale of the axis\n" +"> to better distribute the observations in the space of the plot.\n" +">\n" +"> - Replace the box plot with a violin plot, see `geom_violin()`\n" +"> - Represent weight on the log10 scale, see `scale_y_log10()`\n" +"> - Add color to the datapoints on your boxplot according to the plot from which\n" +"> the sample was taken (`plot_id`)\n" +">\n" +"> Hint: Check the class for `plot_id`. By using `factor()` within the `aes`\n" +"> mapping of a variable, `plotnine` will handle the values as category values.\n" +">\n" +"> > ## Answers\n" +"> >\n" +"> > ~~~\n" +"> > (p9.ggplot(data=surveys_complete,\n" +"> > mapping=p9.aes(x='species_id',\n" +"> > y='weight',\n" +"> > color='factor(plot_id)'))\n" +"> > + p9.geom_jitter(alpha=0.3)\n" +"> > + p9.geom_violin(alpha=0, color=\"0.7\")\n" +"> > + p9.scale_y_log10()\n" +"> > )\n" +"> > ~~~\n" +"> > {: .language-python}\n" +"> > ![png](../fig/06_challenge_boxplot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:348 +# header +msgid "## Plotting time series data" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:350 +msgid "Let's calculate number of counts per year for each species. To do that we need\n" +"to group data first and count the species (`species_id`) within each group." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:353 +# code block +msgid "~~~\n" +"yearly_counts = surveys_complete.groupby(['year', 'species_id'])['species_id'].count()\n" +"yearly_counts\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:359 +msgid "When checking the result of the previous calculation, we actually have both the\n" +"`year` and the `species_id` as a row index. We can reset this index to use both\n" +"as column variable:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:363 +# code block +msgid "~~~\n" +"yearly_counts = yearly_counts.reset_index(name='counts')\n" +"yearly_counts\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:369 +msgid "Timelapse data can be visualised as a line plot (`geom_line`) with years on `x`\n" +"axis and counts on the `y` axis." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:373 +# code block +msgid "~~~\n" +"(p9.ggplot(data=yearly_counts,\n" +" mapping=p9.aes(x='year',\n" +" y='counts'))\n" +" + p9.geom_line()\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:382 +msgid "Unfortunately this does not work, because we plot data for all the species\n" +"together. We need to tell `plotnine` to draw a line for each species by\n" +"modifying the aesthetic function and map the species_id to the color:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:386 +# code block +msgid "~~~\n" +"(p9.ggplot(data=yearly_counts,\n" +" mapping=p9.aes(x='year',\n" +" y='counts',\n" +" color='species_id'))\n" +" + p9.geom_line()\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:396 +msgid "![png](../fig/06_time_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:398 +# header +msgid "## Faceting" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:400 +msgid "As any other library supporting the Grammar of Graphics, `plotnine` has a\n" +"special technique called *faceting* that allows to split one plot into multiple\n" +"plots based on a factor variable included in the dataset." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:404 +msgid "Consider our scatter plot of the `weight` versus the `hindfoot_length` from the\n" +"previous sections:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:417 +msgid "We can now keep the same code and at the `facet_wrap` on a chosen variable to\n" +"split out the graph and make a separate graph for each of the groups in that\n" +"variable. As an example, use `sex`:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:421 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight',\n" +" y='hindfoot_length',\n" +" color='species_id'))\n" +" + p9.geom_point(alpha=0.1)\n" +" + p9.facet_wrap(\"sex\")\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:430 +msgid "{: .language-python}\n" +"![png](../fig/06_facet_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:433 +msgid "We can apply the same concept on any of the available categorical variables:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:435 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight',\n" +" y='hindfoot_length',\n" +" color='species_id'))\n" +" + p9.geom_point(alpha=0.1)\n" +" + p9.facet_wrap(\"plot_id\")\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:446 +msgid "![png](../fig/06_facet_all_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:448 +msgid "The `facet_wrap` geometry extracts plots into an arbitrary number of dimensions\n" +"to allow them to cleanly fit on one page. On the other hand, the `facet_grid`\n" +"geometry allows you to explicitly specify how you want your plots to be\n" +"arranged via formula notation (`rows ~ columns`; a `.` can be used as a\n" +"placeholder that indicates only one row or column)." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:454 +# code block +msgid "~~~\n" +"# only select the years of interest\n" +"survey_2000 = surveys_complete[surveys_complete[\"year\"].isin([2000, 2001])]\n" +"\n" +"(p9.ggplot(data=survey_2000,\n" +" mapping=p9.aes(x='weight',\n" +" y='hindfoot_length',\n" +" color='species_id'))\n" +" + p9.geom_point(alpha=0.1)\n" +" + p9.facet_grid(\"year ~ sex\")\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:466 +msgid "{: .language-python}\n" +"![png](../fig/06_select_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:469 +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:489 +# blockquote, which can be cascaded +msgid "> ## Challenge - facetting" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:470 +# blockquote, which can be cascaded +msgid "> Create a separate plot for each of the species that depicts how the average" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:471 +# blockquote, which can be cascaded +msgid "> weight of the species changes through the years." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:472 +msgid ">\n" +"> > ## Answers\n" +"> > yearly_weight = surveys_complete.groupby(['year', 'species_id'])['weight'].mean().reset_index()\n" +"> >\n" +"> > ~~~\n" +"> > (p9.ggplot(data=yearly_weight,\n" +"> > mapping=p9.aes(x='year',\n" +"> > y='weight'))\n" +"> > + p9.geom_line()\n" +"> > + p9.facet_wrap(\"species_id\")\n" +"> > )\n" +"> > ~~~\n" +"> > {: .language-python}" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:490 +# blockquote, which can be cascaded +msgid "> Based on the previous exercise, visually compare how the weights of male and" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:491 +# blockquote, which can be cascaded +msgid "> females has changed through time by creating a separate plot for each sex and" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:492 +# blockquote, which can be cascaded +msgid "> an individual color assigned to each `species_id`." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:493 +msgid ">\n" +"> > ## Answers\n" +"> > yearly_weight = surveys_complete.groupby(['year', 'species_id', 'sex'])['weight'].mean().reset_index()\n" +"> >\n" +"> > (p9.ggplot(data=yearly_weight,\n" +"> > mapping=p9.aes(x='year',\n" +"> > y='weight',\n" +"> > color='species_id'))\n" +"> > + p9.geom_line()\n" +"> > + p9.facet_wrap(\"sex\")\n" +"> > )\n" +"> > {: .language-python}" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:509 +# header +msgid "## Further customization" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:511 +msgid "As the syntax of `plotnine` follows the original R package `ggplot2`, the\n" +"documentation of `ggplot2` can provide information and inspiration to customize\n" +"graphs. Take a look at the `ggplot2` [cheat sheet][ggplot2-cheat-sheet], and think of ways to\n" +"improve the plot. You can write down some of your ideas as comments in the Etherpad." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:516 +msgid "The theming options provide a rich set of visual adaptations. Consider the\n" +"following example of a bar plot with the counts per year." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:519 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='factor(year)'))\n" +" + p9.geom_bar()\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:527 +msgid "![png](../fig/06_overlap_bars.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:529 +msgid "Notice that we use the `year` here as a categorical variable by using the\n" +"`factor` functionality. However, by doing so, we have the individual year\n" +"labels overlapping with each other. The `theme` functionality provides a way to\n" +"rotate the text of the x-axis labels:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:534 +# code block +msgid "~~~\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='factor(year)'))\n" +" + p9.geom_bar()\n" +" + p9.theme_bw()\n" +" + p9.theme(axis_text_x = p9.element_text(angle=90))\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:544 +msgid "![png](../fig/06_good_bars.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:546 +msgid "When you like a specific set of theme-customizations you created, you can save\n" +"them as an object to easily apply them to other plots you may create:" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:550 +# code block +msgid "~~~\n" +"my_custom_theme = p9.theme(axis_text_x = p9.element_text(color=\"grey\", size=10,\n" +" angle=90, hjust=.5),\n" +" axis_text_y = p9.element_text(color=\"grey\", size=10))\n" +"(p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='factor(year)'))\n" +" + p9.geom_bar()\n" +" + my_custom_theme\n" +")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:562 +msgid "![png](../fig/06_theme_plot.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:564 +# blockquote, which can be cascaded +msgid "> ## Challenge - customization" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:565 +# blockquote, which can be cascaded +msgid "> Please take another five minutes to either improve one of the plots" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:566 +# blockquote, which can be cascaded +msgid "> generated in this exercise or create a beautiful graph of your own." +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:567 +msgid ">\n" +"> Here are some ideas:\n" +">\n" +"> * See if you can change thickness of lines for the line plot .\n" +"> * Can you find a way to change the name of the legend? What about its labels?\n" +"> * Use a different color palette (see )" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:576 +msgid "After creating your plot, you can save it to a file in your favourite format.\n" +"You can easily change the dimension (and its resolution) of your plot by\n" +"adjusting the appropriate arguments (`width`, `height` and `dpi`):" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:581 +# code block +msgid "~~~\n" +"my_plot = (p9.ggplot(data=surveys_complete,\n" +" mapping=p9.aes(x='weight', y='hindfoot_length'))\n" +" + p9.geom_point()\n" +")\n" +"my_plot.save(\"scatterplot.png\", width=10, height=10, dpi=300)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/07-visualization-ggplot-python.md:590 +msgid "[ggplot2-cheat-sheet]: https://www.rstudio.com/wp-content/uploads/2015/08/ggplot2-cheatsheet.pdf\n" +"[ggplot2]: https://ggplot2.tidyverse.org\n" +"[grammar-of-graphics]: http://link.springer.com/book/10.1007%2F0-387-28695-0\n" +"[plotnine-api]: https://plotnine.readthedocs.io/en/stable/api.html#color-and-fill-scales\n" +"[plotnine]: https://plotnine.readthedocs.io/en/stable" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:1 +# Front Matter +msgid "---\n" +"title: Data Ingest and Visualization - Matplotlib and Pandas\n" +"teaching: 40\n" +"exercises: 65\n" +"questions:\n" +" - \"What other tools can I use to create plots apart from ggplot?\"\n" +" - \"Why should I use Python to create plots?\"\n" +"objectives:\n" +" - \"Import the pyplot toolbox to create figures in Python.\"\n" +" - \"Use matplotlib to make adjustments to Pandas or plotnine objects.\"\n" +"keypoints:\n" +" - \"Matplotlib is the engine behind plotnine and Pandas plots.\"\n" +" - \"Object-based nature of matplotlib plots enables their detailed customization after they have been created.\"\n" +" - \"Export plots to a file using the `savefig` method.\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:18 +# header +msgid "## Putting it all together" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:20 +msgid "Up to this point, we have walked through tasks that are often\n" +"involved in handling and processing data using the workshop ready cleaned\n" +"files that we have provided. In this wrap-up exercise, we will perform\n" +"many of the same tasks with real data sets. This lesson also covers data\n" +"visualization." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:26 +msgid "As opposed to the previous ones, this lesson does not give step-by-step\n" +"directions to each of the tasks. Use the lesson materials you've already gone\n" +"through as well as the Python documentation to help you along." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:30 +# header +msgid "## Obtain data" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:32 +msgid "There are many repositories online from which you can obtain data. We are\n" +"providing you with one data file to use with these exercises, but feel free to\n" +"use any data that is relevant to your research. The file\n" +"[`bouldercreek_09_2013.txt`]({{ page.root }}/data/bouldercreek_09_2013.txt)\n" +"contains stream discharge data, summarized at 15\n" +"15 minute intervals (in cubic feet per second) for a streamgage on Boulder\n" +"Creek at North 75th Street (USGS gage06730200) for 1-30 September 2013. If you'd\n" +"like to use this dataset, please find it in the data folder." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:41 +# header +msgid "## Clean up your data and open it using Python and Pandas" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:43 +msgid "To begin, import your data file into Python using Pandas. Did it fail? Your data\n" +"file probably has a header that Pandas does not recognize as part of the data\n" +"table. Remove this header, but do not simply delete it in a text editor! Use\n" +"either a shell script or Python to do this - you wouldn't want to do it by hand\n" +"if you had many files to process." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:49 +msgid "If you are still having trouble importing the data as a table using Pandas,\n" +"check the documentation. You can open the docstring in an ipython notebook using\n" +"a question mark. For example:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:53 +# code block +msgid "~~~\n" +"import pandas as pd\n" +"pd.read_csv?\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:59 +msgid "Look through the function arguments to see if there is a default value that is\n" +"different from what your file requires (Hint: the problem is most likely the\n" +"delimiter or separator. Common delimiters are `','` for comma, `' '` for space,\n" +"and `'\\t'` for tab)." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:64 +msgid "Create a DataFrame that includes only the values of the data that are useful to\n" +"you. In the streamgage file, those values might be the date, time, and discharge\n" +"measurements. Convert any measurements in imperial units into SI units. You can\n" +"also change the name of the columns in the DataFrame like this:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:69 +# code block +msgid "~~~\n" +"df = pd.DataFrame({'1stcolumn':[100,200], '2ndcolumn':[10,20]}) # this just creates a DataFrame for the example!\n" +"print('With the old column names:\\n') # the \\n makes a new line, so it's easier to see\n" +"print(df)\n" +"\n" +"df.columns = ['FirstColumn','SecondColumn'] # rename the columns!\n" +"print('\\n\\nWith the new column names:\\n')\n" +"print(df)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:80 +# code block +msgid "~~~\n" +"With the old column names:\n" +"\n" +" 1stcolumn 2ndcolumn\n" +"0 100 10\n" +"1 200 20\n" +"\n" +"\n" +"With the new column names:\n" +"\n" +" FirstColumn SecondColumn\n" +"0 100 10\n" +"1 200 20\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:96 +# header +msgid "## Matplotlib package" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:98 +msgid "[Matplotlib](https://matplotlib.org/) is a Python package that is widely used throughout the scientific Python community to create high-quality and publication-ready graphics. It supports a wide range of raster and vector graphics formats including PNG, PostScript, EPS, PDF and SVG." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:100 +msgid "Moreover, matplotlib is the actual engine behind the plotting capabilities of both Pandas and plotnine packages. For example, when we call the `.plot` method on Pandas data objects, we actually use the matplotlib package." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:102 +msgid "First, import the pyplot toolbox:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:104 +# code block +msgid "~~~\n" +"import matplotlib.pyplot as plt\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:109 +msgid "Now, let's read data and plot it!" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:111 +# code block +msgid "~~~\n" +"surveys = pd.read_csv(\"data/surveys.csv\")\n" +"my_plot = surveys.plot(\"hindfoot_length\", \"weight\", kind=\"scatter\")\n" +"plt.show() # not necessary in Jupyter Notebooks\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:118 +msgid "![Scatter plot of survey data set](../fig/08_scatter_surveys.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:120 +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:134 +# blockquote, which can be cascaded +msgid "> ## Tip" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:121 +# blockquote, which can be cascaded +msgid "> By default, matplotlib creates a figure in a separate window. When using" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:122 +# blockquote, which can be cascaded +msgid "> Jupyter notebooks, we can make figures appear in-line within the notebook by" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:123 +# blockquote, which can be cascaded +msgid "> executing:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:124 +msgid ">\n" +"> ~~~\n" +"> %matplotlib inline\n" +"> ~~~\n" +"> {: .language-python}" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:131 +msgid "The returned object is a matplotlib object (check it yourself with `type(my_plot)`),\n" +"to which we may make further adjustments and refinements using other matplotlib methods." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:135 +# blockquote, which can be cascaded +msgid "> Matplotlib itself can be overwhelming, so a useful strategy is to" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:136 +# blockquote, which can be cascaded +msgid "> do as much as you easily can in a convenience layer, _i.e._ start" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:137 +# blockquote, which can be cascaded +msgid "> creating the plot in Pandas or plotnine, and then use matplotlib" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:138 +# blockquote, which can be cascaded +msgid "> for the rest." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:141 +msgid "We will cover a few basic commands for creating and formatting plots with matplotlib in this lesson.\n" +"A great resource for help creating and styling your figures is the matplotlib gallery\n" +"(), which includes plots in many different\n" +"styles and the source codes that create them." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:147 +# header +msgid "### `plt` pyplot versus object-based matplotlib" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:149 +msgid "Matplotlib integrates nicely with the NumPy package and can use NumPy arrays\n" +"as input to the available plot functions. Consider the following example data,\n" +"created with NumPy by drawing 1000 samples from a normal distribution with a mean value of 0 and\n" +"a standard deviation of 0.1:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:154 +# code block +msgid "~~~\n" +"import numpy as np\n" +"sample_data = np.random.normal(0, 0.1, 1000)\n" +"\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:161 +msgid "To plot a histogram of our draws from the normal distribution, we can use the `hist` function directly:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:163 +# code block +msgid "~~~\n" +"plt.hist(sample_data)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:168 +msgid "![Histogram of 1000 samples from normal distribution](../fig/08-normal-distribution.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:170 +# blockquote, which can be cascaded +msgid "> ## Tip: Cross-Platform Visualization of Figures" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:171 +# blockquote, which can be cascaded +msgid "> Jupyter Notebooks make many aspects of data analysis and visualization much simpler. This includes" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:172 +# blockquote, which can be cascaded +msgid "> doing some of the labor of visualizing plots for you. But, not every one of your collaborators" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:173 +# blockquote, which can be cascaded +msgid "> will be using a Jupyter Notebook. The `.show()` command allows you to visualize plots" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:174 +# blockquote, which can be cascaded +msgid "> when working at the command line, with a script, or at the IPython interpreter. In the" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:175 +# blockquote, which can be cascaded +msgid "> previous example, adding `plt.show()` after the creation of the plot will enable your" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:176 +# blockquote, which can be cascaded +msgid "> colleagues who aren't using a Jupyter notebook to reproduce your work on their platform." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:179 +msgid "or create matplotlib `figure` and `axis` objects first and subsequently add a histogram with 30\n" +"data bins:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:182 +# code block +msgid "~~~\n" +"fig, ax = plt.subplots() # initiate an empty figure and axis matplotlib object\n" +"ax.hist(sample_data, 30)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:188 +msgid "Although the latter approach requires a little bit more code to create the same plot,\n" +"the advantage is that it gives us **full control** over the plot and we can add new items\n" +"such as labels, grid lines, title, and other visual elements. For example, we can add\n" +"additional axes to the figure and customize their labels:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:193 +# code block +msgid "~~~\n" +"fig, ax1 = plt.subplots() # prepare a matplotlib figure\n" +"ax1.hist(sample_data, 30)\n" +"\n" +"# Add a plot of a Beta distribution\n" +"a = 5\n" +"b = 10\n" +"beta_draws = np.random.beta(a, b)\n" +"# adapt the labels\n" +"ax1.set_ylabel('density')\n" +"ax1.set_xlabel('value')\n" +"\n" +"# add additional axes to the figure\n" +"ax2 = fig.add_axes([0.125, 0.575, 0.3, 0.3])\n" +"#ax2 = fig.add_axes([left, bottom, right, top])\n" +"ax2.hist(beta_draws)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:212 +msgid "![Plot with additional axes](../fig/08-dualdistribution.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:214 +# blockquote, which can be cascaded +msgid "> ## Challenge - Drawing from distributions" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:215 +# blockquote, which can be cascaded +msgid "> Have a look at the NumPy" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:216 +# blockquote, which can be cascaded +msgid "> random documentation ." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:217 +# blockquote, which can be cascaded +msgid "> Choose a distribution you have no familiarity with, and try to sample from and visualize it." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:222 +# header +msgid "### Link matplotlib, Pandas and plotnine" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:224 +msgid "When we create a plot using pandas or plotnine, both libraries use matplotlib\n" +"to create those plots. The plots created in pandas or plotnine are matplotlib\n" +"objects, which enables us to use some of the advanced plotting options available\n" +"in the matplotlib library. Because the objects output by pandas and plotnine\n" +"can be read by matplotlib, we have many more options than any one library can\n" +"provide, offering a consistent environment to make publication-quality visualizations." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:231 +# code block +msgid "~~~\n" +"fig, ax1 = plt.subplots() # prepare a matplotlib figure\n" +"\n" +"surveys.plot(\"hindfoot_length\", \"weight\", kind=\"scatter\", ax=ax1)\n" +"\n" +"# Provide further adaptations with matplotlib:\n" +"ax1.set_xlabel(\"Hindfoot length\")\n" +"ax1.tick_params(labelsize=16, pad=8)\n" +"fig.suptitle('Scatter plot of weight versus hindfoot length', fontsize=15)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:243 +msgid "![Extended version of scatter plot surveys](../fig/08_scatter_surveys_extended.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:245 +msgid "To retrieve the matplotlib figure object from plotnine for customization, use the `draw()` function in plotnine:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:247 +# code block +msgid "~~~\n" +"import plotnine as p9\n" +"myplot = (p9.ggplot(data=surveys,\n" +" mapping=p9.aes(x='hindfoot_length', y='weight')) +\n" +" p9.geom_point())\n" +"\n" +"# convert output plotnine to a matplotlib object\n" +"my_plt_version = myplot.draw()\n" +"\n" +"# Provide further adaptations with matplotlib:\n" +"p9_ax = my_plt_version.axes[0] # each subplot is an item in a list\n" +"p9_ax.set_xlabel(\"Hindfoot length\")\n" +"p9_ax.tick_params(labelsize=16, pad=8)\n" +"p9_ax.set_title('Scatter plot of weight versus hindfoot length', fontsize=15)\n" +"plt.show() # not necessary in Jupyter Notebooks\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:265 +msgid "![Extended version of plotnine scatter plot](../fig/08_scatter_surveys_plotnine.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:267 +# blockquote, which can be cascaded +msgid "> ## Challenge - Pandas and matplotlib" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:268 +# blockquote, which can be cascaded +msgid "> Load the streamgage data set with Pandas, subset the week of the 2013 Front Range flood" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:269 +# blockquote, which can be cascaded +msgid "> (September 11 through 15) and create a hydrograph (line plot) of the discharge data using" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:270 +# blockquote, which can be cascaded +msgid "> Pandas, linking it to an empty maptlotlib `ax` object. Create a second axis that displays the" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:271 +# blockquote, which can be cascaded +msgid "> whole dataset. Adapt the title and axes' labels using matplotlib." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:272 +msgid ">\n" +"> > ## Answers\n" +"> >\n" +"> > ~~~\n" +"> > discharge = pd.read_csv(\"data/bouldercreek_09_2013.txt\",\n" +"> > skiprows=27, delimiter=\"\\t\",\n" +"> > names=[\"agency\", \"site_id\", \"datetime\",\n" +"> > \"timezone\", \"discharge\", \"discharge_cd\"])\n" +"> > discharge[\"datetime\"] = pd.to_datetime(discharge[\"datetime\"])\n" +"> > front_range = discharge[(discharge[\"datetime\"] >= \"2013-09-09\") &\n" +"> > (discharge[\"datetime\"] < \"2013-09-15\")]\n" +"> >\n" +"> > fig, ax = plt.subplots()\n" +"> > front_range.plot(x =\"datetime\", y=\"discharge\", ax=ax)\n" +"> > ax.set_xlabel(\"\") # no label\n" +"> > ax.set_ylabel(\"Discharge, cubic feet per second\")\n" +"> > ax.set_title(\" Front Range flood event 2013\")\n" +"> > discharge = pd.read_csv(\"../data/bouldercreek_09_2013.txt\",\n" +"> > skiprows=27, delimiter=\"\\t\",\n" +"> > names=[\"agency\", \"site_id\", \"datetime\",\n" +"> > \"timezone\", \"flow_rate\", \"height\"])\n" +"> > fig, ax = plt.subplots()\n" +"> > flood = discharge[(discharge[\"datetime\"] >= \"2013-09-11\") &\n" +"> > (discharge[\"datetime\"] < \"2013-09-15\")]\n" +"> >\n" +"> > ax2 = fig.add_axes([0.65, 0.575, 0.25, 0.3])\n" +"> > flood.plot(x =\"datetime\", y=\"flow_rate\", ax=ax)\n" +"> > discharge.plot(x =\"datetime\", y=\"flow_rate\", ax=ax2)\n" +"> > ax2.legend().set_visible(False)\n" +"> > ax.set_xlabel(\"\") # no label\n" +"> > ax.set_ylabel(\"Discharge, cubic feet per second\")\n" +"> > ax.legend().set_visible(False)\n" +"> > ax.set_title(\" Front Range flood event 2013\")\n" +"> > discharge = pd.read_csv(\"../data/bouldercreek_09_2013.txt\",\n" +"> > skiprows=27, delimiter=\"\\t\",\n" +"> > names=[\"agency\", \"site_id\", \"datetime\",\n" +"> > \"timezone\", \"flow_rate\", \"height\"])\n" +"> > fig, ax = plt.subplots()\n" +"> > flood = discharge[(discharge[\"datetime\"] >= \"2013-09-11\") &\n" +"> > (discharge[\"datetime\"] < \"2013-09-15\")]\n" +"> >\n" +"> > ax2 = fig.add_axes([0.65, 0.575, 0.25, 0.3])\n" +"> > flood.plot(x =\"datetime\", y=\"flow_rate\", ax=ax)\n" +"> > discharge.plot(x =\"datetime\", y=\"flow_rate\", ax=ax2)\n" +"> > ax2.legend().set_visible(False)\n" +"> >\n" +"> > ax.set_xlabel(\"\") # no label\n" +"> > ax.set_ylabel(\"Discharge, cubic feet per second\")\n" +"> > ax.legend().set_visible(False)\n" +"> > ax.set_title(\" Front Range flood event 2013\")\n" +"> > ~~~\n" +"> > {: .language-python}\n" +"> >\n" +"> > ![Flood event plot](../fig/08_flood_event.png)" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:329 +# header +msgid "### Saving matplotlib figures" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:331 +msgid "Once satisfied with the resulting plot, you can save the plot with the `.savefig(*args)` method from matplotlib:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:333 +# code block +msgid "~~~\n" +"fig.savefig(\"my_plot_name.png\")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:338 +msgid "which will save the `fig` created using Pandas/matplotlib as a png file with the name `my_plot_name`" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:340 +# blockquote, which can be cascaded +msgid "> ## Tip: Saving figures in different formats" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:341 +# blockquote, which can be cascaded +msgid "> Matplotlib recognizes the extension used in the filename and" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:342 +# blockquote, which can be cascaded +msgid "> supports (on most computers) png, pdf, ps, eps and svg formats." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:345 +# blockquote, which can be cascaded +msgid "> ## Challenge - Saving figure to file" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:346 +# blockquote, which can be cascaded +msgid "> Check the documentation of the `savefig` method and check how" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:347 +# blockquote, which can be cascaded +msgid "> you can comply to journals requiring figures as `pdf` file with" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:348 +# blockquote, which can be cascaded +msgid "> dpi >= 300." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:349 +msgid ">\n" +"> > ## Answers\n" +"> >\n" +"> > ~~~\n" +"> > fig.savefig(\"my_plot_name.pdf\", dpi=300)\n" +"> > ~~~\n" +"> > {: .language-python}" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:359 +# header +msgid "## Make other types of plots:" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:361 +msgid "Matplotlib can make many other types of plots in much the same way that it makes two-dimensional line plots. Look through the examples in\n" +" and try a few of them (click on the\n" +"\"Source code\" link and copy and paste into a new cell in ipython notebook or\n" +"save as a text file with a `.py` extension and run in the command line)." +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:366 +# blockquote, which can be cascaded +msgid "> ## Challenge - Final Plot" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:367 +# blockquote, which can be cascaded +msgid "> Display your data using one or more plot types from the example gallery. Which" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:368 +# blockquote, which can be cascaded +msgid "> ones to choose will depend on the content of your own data file. If you are" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:369 +# blockquote, which can be cascaded +msgid "> using the streamgage file [`bouldercreek_09_2013.txt`]({{ page.root }}/data/bouldercreek_09_2013.txt), you could make a" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:370 +# blockquote, which can be cascaded +msgid "> histogram of the number of days with a given mean discharge, use bar plots" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:371 +# blockquote, which can be cascaded +msgid "> to display daily discharge statistics, or explore the different ways matplotlib" +msgstr "" + +#: python-ecology-lesson/_episodes/08-putting-it-all-together.md:372 +# blockquote, which can be cascaded +msgid "> can handle dates and times for figures." +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:1 +# Front Matter +msgid "---\n" +"title: Accessing SQLite Databases Using Python and Pandas\n" +"teaching: 20\n" +"exercises: 25\n" +"questions:\n" +" - \"What if my data are stored in an SQL database? Can I manage them with Python?\"\n" +" - \"How can I write data from Python to be used with SQL?\"\n" +"objectives:\n" +" - \"Use the sqlite3 module to interact with a SQL database.\"\n" +" - \"Access data stored in SQLite using Python.\"\n" +" - \"Describe the difference in interacting with data stored as a CSV file versus in SQLite.\"\n" +" - \"Describe the benefits of accessing data using a database compared to a CSV file.\"\n" +"keypoints:\n" +" - \"sqlite3 provides a SQL-like interface to read, query, and write SQL databases from Python.\"\n" +" - \"sqlite3 can be used with Pandas to read SQL data to the familiar Pandas DataFrame.\"\n" +" - \"Pandas and sqlite3 can also be used to transfer between the CSV and SQL formats.\"\n" +"---" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:19 +# header +msgid "## Python and SQL" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:21 +msgid "When you open a CSV in python, and assign it to a variable name, you are using\n" +"your computers memory to save that variable. Accessing data from a database like\n" +"SQL is not only more efficient, but also it allows you to subset and import only\n" +"the parts of the data that you need." +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:26 +msgid "In the following lesson, we'll see some approaches that can be taken to do so." +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:28 +# header +msgid "### The `sqlite3` module" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:30 +msgid "The [sqlite3] module provides a straightforward interface for interacting with\n" +"SQLite databases. A connection object is created using `sqlite3.connect()`; the\n" +"connection must be closed at the end of the session with the `.close()` command.\n" +"While the connection is open, any interactions with the database require you to\n" +"make a cursor object with the `.cursor()` command. The cursor is then ready to\n" +"perform all kinds of operations with `.execute()`." +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:37 +msgid "[sqlite3]: https://docs.python.org/3/library/sqlite3.html" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:39 +# code block +msgid "~~~\n" +"import sqlite3\n" +"\n" +"# Create a SQL connection to our SQLite database\n" +"con = sqlite3.connect(\"data/portal_mammals.sqlite\")\n" +"\n" +"cur = con.cursor()\n" +"\n" +"# The result of a \"cursor.execute\" can be iterated over by row\n" +"for row in cur.execute('SELECT * FROM species;'):\n" +" print(row)\n" +"\n" +"# Be sure to close the connection\n" +"con.close()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:56 +# header +msgid "### Queries" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:58 +msgid "One of the most common ways to interact with a database is by querying:\n" +"retrieving data based on some search parameters. Use a SELECT statement string.\n" +"The query is returned as a single tuple or a tuple of tuples. Add a WHERE\n" +"statement to filter your results based on some parameter." +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:63 +# code block +msgid "~~~\n" +"import sqlite3\n" +"\n" +"# Create a SQL connection to our SQLite database\n" +"con = sqlite3.connect(\"data/portal_mammals.sqlite\")\n" +"\n" +"cur = con.cursor()\n" +"\n" +"# Return all results of query\n" +"cur.execute('SELECT plot_id FROM plots WHERE plot_type=\"Control\"')\n" +"cur.fetchall()\n" +"\n" +"# Return first result of query\n" +"cur.execute('SELECT species FROM species WHERE taxa=\"Bird\"')\n" +"cur.fetchone()\n" +"\n" +"# Be sure to close the connection\n" +"con.close()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:84 +# header +msgid "## Accessing data stored in SQLite using Python and Pandas" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:86 +msgid "Using pandas, we can import results of a SQLite query into a dataframe. Note\n" +"that you can use the same SQL commands / syntax that we used in the SQLite\n" +"lesson. An example of using pandas together with sqlite is below:" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:90 +# code block +msgid "~~~\n" +"import pandas as pd\n" +"import sqlite3\n" +"\n" +"# Read sqlite query results into a pandas DataFrame\n" +"con = sqlite3.connect(\"data/portal_mammals.sqlite\")\n" +"df = pd.read_sql_query(\"SELECT * from surveys\", con)\n" +"\n" +"# Verify that result of SQL query is stored in the dataframe\n" +"print(df.head())\n" +"\n" +"con.close()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:105 +# header +msgid "## Storing data: CSV vs SQLite" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:107 +msgid "Storing your data in an SQLite database can provide substantial performance\n" +"improvements when reading/writing compared to CSV. The difference in performance\n" +"becomes more noticeable as the size of the dataset grows (see for example [these\n" +"benchmarks])." +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:112 +msgid "[these benchmarks]: http://sebastianraschka.com/Articles/2013_sqlite_database.html#results-and-conclusions" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:115 +# blockquote, which can be cascaded +msgid "> ## Challenge - SQL" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:116 +msgid ">\n" +"> 1. Create a query that contains survey data collected between 1998 - 2001 for\n" +"> observations of sex \"male\" or \"female\" that includes observation's genus and\n" +"> species and site type for the sample. How many records are returned?\n" +">\n" +"> 2. Create a dataframe that contains the total number of observations (count)\n" +"> made for all years, and sum of observation weights for each site, ordered by\n" +"> site ID." +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:126 +# header +msgid "## Storing data: Create new tables using Pandas" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:128 +msgid "We can also us pandas to create new tables within an SQLite database. Here, we run we re-do an\n" +"exercise we did before with CSV files using our SQLite database. We first read in our survey data,\n" +"then select only those survey results for 2002, and then save it out to its own table so we can work\n" +"with it on its own later." +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:133 +# code block +msgid "~~~\n" +"import pandas as pd\n" +"import sqlite3\n" +"\n" +"con = sqlite3.connect(\"data/portal_mammals.sqlite\")\n" +"\n" +"# Load the data into a DataFrame\n" +"surveys_df = pd.read_sql_query(\"SELECT * from surveys\", con)\n" +"\n" +"# Select only data for 2002\n" +"surveys2002 = surveys_df[surveys_df.year == 2002]\n" +"\n" +"# Write the new DataFrame to a new SQLite table\n" +"surveys2002.to_sql(\"surveys2002\", con, if_exists=\"replace\")\n" +"\n" +"con.close()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:152 +# blockquote, which can be cascaded +msgid "> ## Challenge - Saving your work" +msgstr "" + +#: python-ecology-lesson/_episodes/09-working-with-sql.md:153 +msgid ">\n" +"> 1. For each of the challenges in the previous challenge block, modify your code to save the\n" +"> results to their own tables in the portal database.\n" +">\n" +"> 2. What are some of the reasons you might want to save the results of your queries back into the\n" +"> database? What are some of the reasons you might avoid doing this." +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:1 +# Front Matter +msgid "---\n" +"layout: page\n" +"title: About Contributors\n" +"permalink: /contributors/\n" +"---" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:6 +msgid "The materials in this python-ecology-lesson repository were initially developed\n" +"and adapted and continue to be revised by many contributors. Some of the lessons\n" +"were adapted from Software Carpentry materials." +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:10 +msgid "The first Python Data Carpentry workshop was run at University of Miami on March\n" +"30 2015 John Gosset and Francois Michonneau. During this time materials were\n" +"refined and they presented again at the UCAR Software Engineering Assembly (SEA)\n" +"conference in Boulder, Colorado by Leah Wasser (NEON,Inc) and Mariela Perignon." +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:15 +# header +msgid "## Data" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:17 +msgid "Data is from the paper S. K. Morgan Ernest, Thomas J. Valone, and James H.\n" +"Brown. 2009. Long-term monitoring and experimental manipulation of a Chihuahuan\n" +"Desert ecosystem near Portal, Arizona, USA. Ecology 90:1708." +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:21 +msgid "" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:23 +msgid "Excel data is from the paper Bahlai, C.A., Schaafsma, A.W., Lagos, D., Voegtlin,\n" +"D., Smith, J.L., Welsman, J.A., Xue, Y., DiFonzo, C., Hallett, R.H., 2014.\n" +"Factors inducing migratory forms of soybean aphid and an examination of North\n" +"American spatial dynamics of this species in the context of migratory behavior.\n" +"Agriculture and Forest Entomology. 16, 240-250." +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:29 +msgid "" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:31 +msgid "Master_suction_trap_data_list_uncleaned.csv is a pre-cleaning version of a\n" +"publicly available dataset by David Voegtlin, Doris Lagos, Douglas Landis and\n" +"Christie Bahlai, available at " +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:35 +# header +msgid "## Lessons" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:37 +msgid "The current list of lessons." +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:39 +msgid "Note: these lessons were reorganized, cleaned up and developed further by Leah\n" +"Wasser, Mariela Perignon, John Gosset and François Michonneau in April 2015." +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:42 +# unordered list +msgid " - Short Introduction to Python" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:43 +# unordered list +msgid " - Starting With Data" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:44 +# unordered list +msgid " - Index Slice Subset" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:45 +# unordered list +msgid " - Data Types and Format" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:46 +# unordered list +msgid " - Merging Data" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:47 +# unordered list +msgid " - Data Analysis Automation: Loops and Functions (Developed by Mariela Perignon with minor edits both Leah Wasser)" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:48 +# unordered list +msgid " - Visualizing Data with ggplot (Developed by Jeremy Zucker November 2016)" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:49 +# unordered list +msgid " - Putting It All Together (Developed by Mariela Perignon with minor revisions by Leah Wasser April 2015)" +msgstr "" + +#: python-ecology-lesson/_extras/CONTRIBUTORS.md:50 +# unordered list +msgid " - Accessing SQL using Python (Added by John Gosset with minor revisions by Leah Wasser April 2015)" +msgstr "" + +#: python-ecology-lesson/_extras/about.md:1 +# Front Matter +msgid "---\n" +"layout: page\n" +"title: About\n" +"permalink: /about/\n" +"---" +msgstr "" + +#: python-ecology-lesson/_extras/about.md:6 +msgid "{% include carpentries.html %}" +msgstr "" + +#: python-ecology-lesson/_extras/discuss.md:1 +# Front Matter +msgid "---\n" +"layout: page\n" +"title: Discussion\n" +"permalink: /discuss/\n" +"---" +msgstr "" + +#: python-ecology-lesson/_extras/discuss.md:7 +msgid "No current discussion" +msgstr "" + +#: python-ecology-lesson/_extras/extra_challenges.md:1 +# Front Matter +msgid "--- \n" +"layout: page \n" +"title: \"Extra Challenges\" \n" +"permalink: /extra_challenges/ \n" +"--- " +msgstr "" + +#: python-ecology-lesson/_extras/extra_challenges.md:7 +# header +msgid "# Extra Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/extra_challenges.md:9 +msgid "A collection of challenges that have been either removed from or not (yet) added to the main lesson. " +msgstr "" + +#: python-ecology-lesson/_extras/extra_challenges.md:11 +# blockquote, which can be cascaded +msgid "> ## Looping Over DataFrame" +msgstr "" + +#: python-ecology-lesson/_extras/extra_challenges.md:12 +msgid ">\n" +"> (Please refer to lesson `06-loops-and-functions.md`)\n" +">\n" +"> The file `surveys.csv` in the `data` folder contains 25 years of data from surveys,\n" +"> starting from 1977. We can extract data corresponding to each year in this DataFrame\n" +"> to individual CSV files, by using a `for` loop:\n" +"> \n" +"> ~~~\n" +"> import pandas as pd\n" +"> \n" +"> # Load the data into a DataFrame\n" +"> surveys_df = pd.read_csv('data/surveys.csv')\n" +"> \n" +"> # Loop through a sequence of years and export selected data\n" +"> start_year = 1977\n" +"> end_year = 2002\n" +"> for year in range(start_year, end_year+1):\n" +">\n" +"> # Select data for the year\n" +"> surveys_year = surveys_df[surveys_df.year == year] \n" +">\n" +"> # Write the new DataFrame to a CSV file\n" +"> filename = 'data/surveys' + str(year) + '.csv' \n" +"> surveys_year.to_csv(filename)\n" +"> ~~~\n" +"> {: .language-python}\n" +">\n" +"> What happens if there is no data for a year in a sequence? For example,\n" +"> imagine we used `1976` as the `start_year`\n" +">\n" +"> > ## Solution\n" +"> > We get the expected files for all years between 1977 and 2002,\n" +"> > plus an empty `data/surveys1976.csv` file with only the headers. \n" +"> {: .solution} " +msgstr "" + +#: python-ecology-lesson/_extras/figures.md:1 +# Front Matter +msgid "---\n" +"title: Figures\n" +"---" +msgstr "" + +#: python-ecology-lesson/_extras/figures.md:5 +#: python-ecology-lesson/aio.md:6 +msgid "{% include base_path.html %}" +msgstr "" + +#: python-ecology-lesson/_extras/figures.md:7 +# inline html +msgid "" +msgstr "" + +#: python-ecology-lesson/_extras/figures.md:61 +msgid "{% comment %}\n" +"Create anchor for each one of the episodes.\n" +"{% endcomment %}\n" +"{% for episode in site.episodes %}\n" +"
\n" +"{% endfor %}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:1 +# Front Matter +msgid "---\n" +"layout: page\n" +"title: \"Instructor Notes\"\n" +"permalink: /guide/\n" +"---" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:7 +# header +msgid "# Challenge solutions" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:9 +# header +msgid "## Install the required workshop packages" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:11 +msgid "Please use the instructions in the [Setup][lesson-setup] document to perform installs. If you\n" +"encounter setup issues, please file an issue with the tags 'High-priority'." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:14 +# header +msgid "## Checking installations." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:16 +msgid "In the `_include/scripts` directory, you will find a script called check_env.py This checks the\n" +"functionality of the Anaconda install." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:19 +msgid "By default, Data Carpentry does not have people pull the whole repository with all the scripts and\n" +"addenda. Therefore, you, as the instructor, get to decide how you'd like to provide this script to\n" +"learners, if at all. To use this, students can navigate into `_includes/scripts` terminal, and\n" +"execute the following:" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:24 +# code block +msgid "~~~\n" +"python check_env.py\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:29 +msgid "If learners receive an `AssertionError`, it will inform you how to help them correct this\n" +"installation. Otherwise, it will tell you that the system is good to go and ready for Data\n" +"Carpentry!" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:33 +# header +msgid "## 01-short-introduction-to-Python" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:35 +# header +msgid "### Tuples Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:37 +# unordered list +msgid "* What happens when you execute `a_list[1] = 5`?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:38 +# unordered list +msgid "* What happens when you execute `a_tuple[2] = 5`?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:40 +msgid " As a tuple is immutable, it does not support item assignment. Elements in a list can be altered\n" +" individually." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:43 +# unordered list +msgid "* What does `type(a_tuple)` tell you about `a_tuple`?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:45 +msgid " `tuple`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:47 +# header +msgid "### Dictionaries Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:49 +# unordered list +msgid "* Changing dictionaries: 2. Reassign the value that corresponds to the key `2`." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:51 +msgid "Make sure it is also clear that access to 'the value that corresponds to the key `2`' is actually\n" +"just about the key name. Add for example `rev[10] = \"ten\"` to clarify it is not about the position." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:54 +# code block +msgid "~~~\n" +"rev\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:63 +# code block +msgid "~~~\n" +"rev[2] = \"apple-sauce\"\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:68 +# code block +msgid "~~~\n" +"{1: 'one', 2: 'apple-sauce', 3: 'three'}\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:73 +# header +msgid "## 02-starting-with-data" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:75 +# blockquote, which can be cascaded +msgid "> ## Important Bug Note" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:76 +msgid ">\n" +"> In Pandas prior to 0.18.1 there is a bug causing `surveys_df['weight'].describe()` to return\n" +"> a runtime error." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:81 +# header +msgid "### Dataframe Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:83 +# unordered list +msgid "* `surveys_df.columns`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:85 +msgid " column names (optional: show `surveys_df.columns[4] = \"plotid\"` The index is not mutable; recap of\n" +" previous lesson. Adapting the name is done by `rename` function\n" +" `surveys_df.rename(columns={\"plot_id\": \"plotid\"})`)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:89 +# unordered list +msgid "* `surveys_df.head()`. Also, what does `surveys_df.head(15)` do?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:91 +msgid " Show first 5 lines. Show first 15 lines." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:93 +# unordered list +msgid "* `surveys_df.tail()`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:95 +msgid " Show last 5 lines" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:97 +# unordered list +msgid "* `surveys_df.shape`. Take note of the output of the shape method. What format does it return the" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:98 +msgid " shape of the DataFrame in?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:100 +msgid " `type(surveys_df.shape)` -> `Tuple`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:102 +# header +msgid "### Calculating Statistics Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:104 +# unordered list +msgid "* Create a list of unique plot ID's found in the surveys data. Call it `plot_names`. How many unique" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:105 +msgid " plots are in the data? How many unique species are in the data?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:107 +msgid " `plot_names = pd.unique(surveys_df[\"plot_id\"])` Number of unique plot ID's: `plot_names.size` or\n" +" `len(plot_names)`; Number of unique species in the data: `len(pd.unique(surveys_df[\"species\"]))`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:110 +# unordered list +msgid "* What is the difference between `len(plot_names)` and `surveys_df['plot_id'].nunique()`?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:112 +msgid " Both do result in the same output, making it alternative ways of getting the unique values.\n" +" `nunique` combines the count and unique value extraction." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:115 +# header +msgid "### Grouping Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:117 +# unordered list +msgid "* How many recorded individuals are female `F` and how many male `M`?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:119 +msgid " `grouped_data.count()`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:121 +# unordered list +msgid "* What happens when you group by two columns using the following syntax and then grab mean values?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:123 +msgid " The mean value for each combination of plot and sex is calculated. Remark that the mean does not\n" +" make sense for each variable, so you can specify this column-wise: e.g. I want to know the last\n" +" survey year, median foot-length and mean weight for each plot/sex combination:" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:127 +# code block +msgid "~~~\n" +"surveys_df.groupby(['plot_id','sex']).agg({\"year\": 'min',\n" +" \"hindfoot_length\": 'median',\n" +" \"weight\": 'mean'})\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:134 +# unordered list +msgid "* Summarize the weight values for each plot in your data." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:136 +# code block +msgid "~~~\n" +"surveys_df.groupby(['plot_id'])['weight'].describe()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:141 +# unordered list +msgid "* Another Challenge: What is another way to create a list of species and the associated count of the" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:142 +msgid " records in the data?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:144 +msgid " Instead of getting the column of the groupby and counting it, you can also count on the groupby\n" +" (all columns) and make a selection of the resulting data frame:\n" +" `surveys_df.groupby('species_id').count()[\"record_id\"]`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:148 +# header +msgid "### Plotting Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:150 +# unordered list +msgid "* Create a plot of the average weight across all species per plot." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:152 +# code block +msgid "~~~\n" +"surveys_df.groupby('plot_id').mean()[\"weight\"].plot(kind='bar')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:157 +msgid "![average weight across all species for each plot](../fig/01_chall_bar_meanweight.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:159 +# unordered list +msgid "* Create a plot of total males versus total females for the entire datase." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:161 +# code block +msgid "~~~\n" +"surveys_df.groupby('sex').count()[\"record_id\"].plot(kind='bar')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:164 +msgid "{: .language-python}\n" +"![total males versus total females for the entire dataset](../fig/01_chall_bar_totalsex.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:167 +# header +msgid "## 03-index-slice-subset" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:169 +msgid "Tip: use `.head()` method throughout this lesson to keep your display neater for students.\n" +"Encourage students to try with and without `.head()` to reinforce this useful tool and then to use\n" +"it or not at their preference. For example, if a student worries about keeping up in pace with\n" +"typing, let them know they can skip the `.head()`, but that you'll use it to keep more lines of\n" +"previous steps visible." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:175 +# header +msgid "### Indexing Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:177 +# unordered list +msgid "* What value does the code below return? `a[0]`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:179 +msgid " `1`, as Python starts with element 0 (for Matlab users: this is different!)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:181 +# unordered list +msgid "* How about this: `a[5]`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:183 +#: python-ecology-lesson/_extras/guide.md:191 +msgid " `IndexError`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:185 +# unordered list +msgid "* In the example above, calling `a[5]` returns an error. Why is that?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:187 +msgid " The list has no element with index 5 (going from 0 till 4)." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:189 +# unordered list +msgid "* What about? `a[len(a)]`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:193 +# header +msgid "### Selection Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:195 +# unordered list +msgid "* What happens when you execute:" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:197 +msgid " `surveys_df[0:3]`\n" +" `surveys_df[0:1]` slicing only the first element\n" +" `surveys_df[:5]` slicing from first element makes 0 redundant\n" +" `surveys_df[-1:]` you can count backwards" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:202 +msgid " *Suggestion*: You can also select every Nth row: `surveys_df[1:10:2]`. So, how to interpret\n" +" `surveys_df[::-1]`?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:205 +# unordered list +msgid "* What is the difference between `surveys_df.iloc[0:4, 1:4]` and `surveys_df.loc[0:4, 1:4]`?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:207 +msgid " Check the position, or the name. Cfr. the second is like it would be in a dictionary, asking for\n" +" the key-names. Column names 1:4 do not exist, resulting in an error. Check also the difference\n" +" between `surveys_df.loc[0:4]` and `surveys_df.iloc[0:4]`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:211 +# header +msgid "### Advanced Selection Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:213 +# unordered list +msgid "* Select a subset of rows in the `surveys_df` DataFrame that contain data from the year 1999 and" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:214 +msgid " that contain weight values less than or equal to 8. How many columns did you end up with? What did\n" +" your neighbor get?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:217 +msgid " `surveys_df[(surveys_df[\"year\"] == 1999) & (surveys_df[\"weight\"] <= 8)]`; when only interested in\n" +" how many, the sum of `True` values could be used as well:\n" +" `sum((surveys_df[\"year\"] == 1999) & (surveys_df[\"weight\"] <= 8))`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:221 +# unordered list +msgid "* You can use the `isin` command in Python to query a DataFrame based upon a list of values as" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:222 +msgid " follows: `surveys_df[surveys_df['species_id'].isin([listGoesHere])]`. Use the `isin` function to\n" +" find all plots that contain particular species in the surveys DataFrame. How many records contain\n" +" these values?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:226 +msgid " For example, using `PB` and `PL`:\n" +" `surveys_df[surveys_df['species_id'].isin(['PB', 'PL'])]['plot_id'].unique()` provides a list of\n" +" the plots with these species involved. With\n" +" `surveys_df[surveys_df['species_id'].isin(['PB', 'PL'])].shape` the number of records can be\n" +" derived." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:232 +# unordered list +msgid "* Create a query that finds all rows with a weight value > or equal to 0." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:234 +msgid " `surveys_df[surveys_df[\"weight\"] >= 0]`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:236 +msgid " *Suggestion*: Introduce already that all these slice operations are actually based on a\n" +" *Boolean indexing* operation (next section in the lesson). The filter provides for each record if\n" +" it satisfies (True) or not (False). The slicing itself interprets the True/False of each record." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:240 +# unordered list +msgid "* The `~` symbol in Python can be used to return the OPPOSITE of the selection that you specify in" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:241 +msgid " Python. It is equivalent to \"is not in\". Write a query that selects all rows that are NOT equal to\n" +" 'M' or 'F' in the surveys data." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:244 +# code block +msgid "~~~\n" +"surveys_df[~surveys_df[\"sex\"].isin(['M', 'F'])]\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:249 +# header +msgid "### Masking Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:251 +# unordered list +msgid "* Create a new DataFrame that only contains observations with sex values that are not female or" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:252 +msgid " male. Assign each sex value in the new DataFrame to a new value of 'x'. Determine the number of\n" +" null values in the subset." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:255 +msgid " ~~~\n" +" new = surveys_df[~surveys_df['sex'].isin(['M', 'F'])].copy()\n" +" new['sex']='x'\n" +" print(len(new))\n" +" ~~~\n" +" {: .language-python}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:262 +msgid " Can verify the number of Nan values with `sum(surveys_df['sex'].isnull())`, which is equal to the\n" +" number of none female/male records." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:265 +# unordered list +msgid "* Create a new DataFrame that contains only observations that are of sex male or female and where" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:266 +msgid " weight values are greater than 0. Create a stacked bar plot of average weight by plot with male vs\n" +" female values stacked for each plot." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:269 +msgid " ~~~\n" +" # selection of the data with isin\n" +" stack_selection = surveys_df[(surveys_df['sex'].isin(['M', 'F'])) &\n" +" surveys_df[\"weight\"] > 0.][[\"sex\", \"weight\", \"plot_id\"]]\n" +" # calculate the mean weight for each plot id and sex combination:\n" +" stack_selection = stack_selection.groupby([\"plot_id\", \"sex\"]).mean().unstack()\n" +" # and we can make a stacked bar plot from this:\n" +" stack_selection.plot(kind='bar', stacked=True)\n" +" ~~~\n" +" {: .language-python}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:280 +msgid " *Suggestion*: As we know the other values are all Nan values, we could also select all not null\n" +" values (just preview, more on this in next lesson):\n" +" ~~~\n" +" stack_selection = surveys_df[(surveys_df['sex'].notnull()) &\n" +" surveys_df[\"weight\"] > 0.][[\"sex\", \"weight\", \"plot_id\"]]\n" +" ~~~\n" +" {: .language-python}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:288 +msgid " ![average weight for each plot per sex](../fig/02_chall_stack_levelissue.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:290 +msgid " However, due to the `unstack` command, the legend header contains two levels. In order to remove\n" +" this, the column naming needs to be simplified:\n" +" ~~~\n" +" stack_selection.columns = stack_selection.columns.droplevel()\n" +" ~~~\n" +" {: .language-python}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:297 +msgid " ![average weight for each plot per sex](../fig/02_chall_stack_level.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:299 +# header +msgid "## 04-data-types-and-format" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:301 +# header +msgid "### Challenge - Changing Types" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:303 +# unordered list +msgid "* Try converting the column `plot_id` to floats using `surveys_df.plot_id.astype(\"float\")`." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:304 +msgid "Then, try converting the contents of the `weight` column to an integer type.\n" +"What error messages does Pandas give you? What do these errors mean?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:307 +msgid "Pandas cannot convert types from float to int if the column contains NaN values." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:309 +# header +msgid "### Challenge - Counting" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:311 +# unordered list +msgid "* Count the number of missing values per column. Hint: The method `.count()` gives you the number of" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:312 +msgid " non-NA observations per column. Try looking to the `.isnull()` method." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:314 +# code block +msgid "~~~\n" +"surveys_df.isnull()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:319 +msgid "If the students have trouble generating the output, or anything happens with that, the folder\n" +"`sample_output` in this repository contains the file `surveys_complete.csv` with the data they\n" +"should generate." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:323 +# header +msgid "## 05-merging-data" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:325 +# unordered list +msgid "* In the data folder, there are two survey data files: survey2001.csv and survey2002.csv. Read the" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:326 +msgid " data into Python and combine the files to make one new data frame. Create a plot of average plot\n" +" weight by year grouped by sex. Export your results as a CSV and make sure it reads back into\n" +" Python properly." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:330 +# code block +msgid "~~~\n" +"# read the files:\n" +"survey2001 = pd.read_csv(\"data/survey2001.csv\")\n" +"survey2002 = pd.read_csv(\"data/survey2002.csv\")\n" +"# concatenate\n" +"survey_all = pd.concat([survey2001, survey2002], axis=0)\n" +"# get the weight for each year, grouped by sex:\n" +"weight_year = survey_all.groupby(['year', 'sex']).mean()[\"wgt\"].unstack()\n" +"# plot:\n" +"weight_year.plot(kind=\"bar\")\n" +"plt.tight_layout() # tip(!)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:342 +msgid "{: .language-python}\n" +"![average weight for each year, grouped by sex](../fig/04_chall_weight_year.png)\n" +"~~~\n" +"# writing to file:\n" +"weight_year.to_csv(\"weight_for_year.csv\")\n" +"# reading it back in:\n" +"pd.read_csv(\"weight_for_year.csv\", index_col=0)\n" +"~~~\n" +"{: .language-python}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:352 +# unordered list +msgid "* Create a new DataFrame by joining the contents of the surveys.csv and species.csv tables." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:354 +# code block +msgid "~~~\n" +"merged_left = pd.merge(left=surveys_df,right=species_df, how='left', on=\"species_id\")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:359 +msgid "Then calculate and plot the distribution of:" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:361 +msgid "**1. taxa per plot** (number of species of each taxa per plot):" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:363 +msgid "Species distribution (number of taxa for each plot) can be derived as follows:\n" +"~~~\n" +"merged_left.groupby([\"plot_id\"])[\"taxa\"].nunique().plot(kind='bar')\n" +"~~~\n" +"{: .language-python}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:369 +msgid "![taxa per plot](../fig/04_chall_ntaxa_per_site.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:371 +msgid "*Suggestion*: It is also possible to plot the number of individuals for each taxa in each plot\n" +"(stacked bar chart):\n" +"~~~\n" +"merged_left.groupby([\"plot_id\", \"taxa\"]).count()[\"record_id\"].unstack().plot(kind='bar', stacked=True)\n" +"plt.legend(loc='upper center', ncol=3, bbox_to_anchor=(0.5, 1.05))\n" +"~~~\n" +"{: .language-python}\n" +"(the legend otherwise overlaps the bar plot)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:380 +msgid "![taxa per plot](../fig/04_chall_taxa_per_site.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:382 +msgid "**2. taxa by sex by plot**:\n" +"Providing the Nan values with the M|F values (can also already be changed to 'x'):\n" +"~~~\n" +"merged_left.loc[merged_left[\"sex\"].isnull(), \"sex\"] = 'M|F'\n" +"~~~\n" +"{: .language-python}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:389 +msgid "Number of taxa for each plot/sex combination:\n" +"~~~\n" +"ntaxa_sex_site= merged_left.groupby([\"plot_id\", \"sex\"])[\"taxa\"].nunique().reset_index(level=1)\n" +"ntaxa_sex_site = ntaxa_sex_site.pivot_table(values=\"taxa\", columns=\"sex\", index=ntaxa_sex_site.index)\n" +"ntaxa_sex_site.plot(kind=\"bar\", legend=False)\n" +"plt.legend(loc='upper center', ncol=3, bbox_to_anchor=(0.5, 1.08),\n" +" fontsize='small', frameon=False)\n" +"~~~\n" +"{: .language-python}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:399 +msgid "![taxa per plot per sex](../fig/04_chall_ntaxa_per_site_sex.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:401 +msgid "*Suggestion (for discussion only)*:" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:403 +msgid "The number of individuals for each taxa in each plot per sex can be derived as well." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:405 +# code block +msgid "~~~\n" +"sex_taxa_site = merged_left.groupby([\"plot_id\", \"taxa\", \"sex\"]).count()['record_id']\n" +"sex_taxa_site.unstack(level=[1, 2]).plot(kind='bar', logy=True)\n" +"plt.legend(loc='upper center', ncol=3, bbox_to_anchor=(0.5, 1.15),\n" +" fontsize='small', frameon=False)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:413 +msgid "![taxa per plot per sex](../fig/04_chall_sex_taxa_site_intro.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:415 +msgid "This is not really the best plot choice: not readable,... A first option to make this better, is to\n" +"make facets. However, pandas/matplotlib do not provide this by default. Just as a pure matplotlib\n" +"example (`M|F` if for not-defined sex records):" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:419 +# code block +msgid "~~~\n" +"fig, axs = plt.subplots(3, 1)\n" +"for sex, ax in zip([\"M\", \"F\", \"M|F\"], axs):\n" +" sex_taxa_site[sex_taxa_site[\"sex\"] == sex].plot(kind='bar', ax=ax, legend=False)\n" +" ax.set_ylabel(sex)\n" +" if not ax.is_last_row():\n" +" ax.set_xticks([])\n" +" ax.set_xlabel(\"\")\n" +"axs[0].legend(loc='upper center', ncol=5, bbox_to_anchor=(0.5, 1.3),\n" +" fontsize='small', frameon=False)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:432 +msgid "![taxa per plot per sex](../fig/04_chall_sex_taxa_site.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:434 +msgid "However, it would be better to link to [Seaborn][seaborn] and [Altair][altair] for its kind of\n" +"multivariate visualisations." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:437 +# unordered list +msgid "* In the data folder, there is a plot CSV that contains information about the type associated with" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:438 +msgid "each plot. Use that data to summarize the number of plots by plot type." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:440 +# code block +msgid "~~~\n" +"plot_info = pd.read_csv(\"data/plots.csv\")\n" +"plot_info.groupby(\"plot_type\").count()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:446 +# unordered list +msgid "* Calculate a diversity index of your choice for control vs rodent exclosure plots. The index should" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:447 +msgid "consider both species abundance and number of species. You might choose the simple biodiversity\n" +"index described here which calculates diversity as `the number of species in the plot / the total\n" +"number of individuals in the plot = Biodiversity index.`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:451 +# code block +msgid "~~~\n" +"merged_site_type = pd.merge(merged_left, plot_info, on='plot_id')\n" +"# For each plot, get the number of species for each plot\n" +"nspecies_site = merged_site_type.groupby([\"plot_id\"])[\"species\"].nunique().rename(\"nspecies\")\n" +"# For each plot, get the number of individuals\n" +"nindividuals_site = merged_site_type.groupby([\"plot_id\"]).count()['record_id'].rename(\"nindiv\")\n" +"# combine the two series\n" +"diversity_index = pd.concat([nspecies_site, nindividuals_site], axis=1)\n" +"# calculate the diversity index\n" +"diversity_index['diversity'] = diversity_index['nspecies']/diversity_index['nindiv']\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:464 +msgid "Making a bar chart:" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:466 +# code block +msgid "~~~\n" +"diversity_index['diversity'].plot(kind=\"barh\")\n" +"plt.xlabel(\"Diversity index\")\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:472 +msgid "![taxa per plot per sex](../fig/04_chall_diversity_index.png)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:475 +# header +msgid "## 06-loops-and-functions" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:477 +# header +msgid "### Basic Loop Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:479 +# unordered list +msgid "* What happens if we do not include the `pass` statement?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:481 +msgid " `SyntaxError:`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:483 +# unordered list +msgid "* Rewrite the loop so that the animals are separated by commas, not new lines (Hint: You can" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:484 +msgid "concatenate strings using a plus sign. For example, `print(string1 + string2)` outputs\n" +"'string1string2')." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:487 +# code block +msgid "~~~\n" +"for creature in animals:\n" +" print(creature+',', end='')\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:493 +msgid "This loop also adds a comma after the last animal. A better, loop-free solution would be:\n" +"`','.join(animals)`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:496 +# header +msgid "### Looping Over Dataframe Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:498 +# unordered list +msgid "* Some of the surveys you saved are missing data (they have null values that show up as NaN - Not A" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:499 +msgid "Number - in the DataFrames and do not show up in the text files). Modify the for loop so that the\n" +"entries with null values are not included in the yearly files." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:502 +# code block +msgid "~~~\n" +"surveys_year = surveys_df[surveys_df.year == year].dropna()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:507 +# unordered list +msgid "* Let's say you only want to look at data from a given multiple of years. How would you modify your" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:508 +msgid "loop in order to generate a data file for only every 5th year, starting from 1977?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:510 +msgid "You could just make a list manually, however, why not check the first and last year making use of\n" +"the code itself?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:513 +# code block +msgid "~~~\n" +"n_year = 5 # better overview by making variable from it\n" +"first_year = surveys_df['year'].min()\n" +"last_year = surveys_df['year'].max()\n" +"\n" +"for year in range(first_year, last_year, n_year):\n" +" print(year)\n" +"\n" +" # Select data for the year\n" +" surveys_year = surveys_df[surveys_df.year == year].dropna()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:526 +# unordered list +msgid "* Instead of splitting out the data by years, a colleague wants to do analyses each species" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:527 +msgid "separately. How would you write a unique csv file for each species?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:529 +msgid "Similar to previous example, but use the `species_id` column. `surveys_df['species_id'].unique()`.\n" +"However, the species names would improve interpretation of the file naming. A join with the species:\n" +"`merged_left = pd.merge(left=surveys,right=species, how='left', on=\"species_id\")` and using the\n" +"`species` column." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:534 +# header +msgid "### Functions Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:536 +# unordered list +msgid "* Change the values of the arguments in the function and check its output." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:537 +# unordered list +msgid "* Try calling the function by giving it the wrong number of arguments (not 2), or not assigning the" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:538 +msgid "function call to a variable (no `product_of_inputs =`).\n" +"* Declare a variable inside the function and test to see where it exists (Hint: can you print it\n" +"from outside the function?).\n" +"* Explore what happens when a variable both inside and outside the function have the same name. What\n" +"happens to the global variable when you change the value of the local variable?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:544 +msgid "Show these in a debugging environment to make this more clear!" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:546 +# header +msgid "### Additional Functions Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:548 +# unordered list +msgid "* Add two arguments to the functions we wrote that take the path of the directory where the files" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:549 +msgid "will be written and the root of the file name. Create a new set of files with a different name in\n" +"a different directory." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:552 +# code block +msgid "~~~\n" +"def one_year_csv_writer(this_year, all_data, folder_to_save, root_name):\n" +" \"\"\"\n" +" Writes a csv file for data from a given year.\n" +"\n" +" Parameters\n" +" ---------\n" +" this_year : int\n" +" year for which data is extracted\n" +" all_data: pd.DataFrame\n" +" DataFrame with multi-year data\n" +" folder_to_save : str\n" +" folder to save the data files\n" +" root_name: str\n" +" root of the filenames to save the data\n" +" \"\"\"\n" +"\n" +" # Select data for the year\n" +" surveys_year = all_data[all_data.year == this_year]\n" +"\n" +" # Write the new DataFrame to a csv file\n" +" filename = os.path.join(folder_to_save, ''.join([root_name, str(this_year), '.csv']))\n" +" surveys_year.to_csv(filename)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:576 +msgid "{: .language-python}\n" +"Also adapt function `yearly_data_csv_writer` with the additional inputs." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:579 +# unordered list +msgid "* How could you use the function `yearly_data_csv_writer` to create a csv file for only one year?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:580 +msgid "(Hint: think about the syntax for `range`)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:582 +msgid "Adapt the input arguments, e.g. 1978, 1979." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:584 +# header +msgid "### Output Management Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:586 +# unordered list +msgid "* Make the functions return a list of the files they have written. There are many ways you can do" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:587 +msgid "this (and you should try them all!):\n" +" * either of the functions can print to screen,\n" +" just add `print(\"year \" + str(this_year)+ \" written to disk\")` statement\n" +" * either can use a return statement to give back numbers or strings to their function call,\n" +" * or you can use some combination of the two.\n" +" * You could also try using the os library to list the contents of directories.\n" +" `os.listdir`" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:595 +msgid "Implementation inside the function:\n" +"~~~\n" +"filenames = []\n" +"for year in range(start_year, end_year+1):\n" +" filenames.append(one_year_csv_writer(year, all_data, folder_to_save, root_name))\n" +"return filenames\n" +"~~~\n" +"{: .language-python}" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:604 +# unordered list +msgid "* Explore what happens when variables are declared inside each of the functions versus in the main" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:605 +msgid "(non-indented) body of your code. What is the scope of the variables (where are they visible)?\n" +"What happens when they have the same name but are given different values?" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:608 +# unordered list +msgid "* What type of object corresponds to a variable declared as `None`? (Hint: create a variable set to" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:609 +msgid "`None` and use the function `type()`)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:611 +# code block +msgid "~~~\n" +"NoneType\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:616 +# unordered list +msgid "* Compare the behavior of the function `yearly_data_arg_test` when the arguments have `None` as a" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:617 +msgid "default and when they do not have default values." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:619 +# unordered list +msgid "* What happens if you only include a value for `start_year` in the function call? Can you write the" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:620 +msgid "function call with only a value for `end_year`? (Hint: think about how the function must be\n" +"assigning values to each of the arguments - this is related to the need to put the arguments\n" +"without default values before those with default values in the function definition!)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:624 +# code block +msgid "~~~\n" +"yearly_data_arg_test(surveys_df, end_year=2001)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:629 +# header +msgid "### Functions Modifications Challenges" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:631 +# unordered list +msgid "* Rewrite the `one_year_csv_writer` and `yearly_data_csv_writer` functions to have keyword arguments" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:632 +msgid "with default values." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:634 +# code block +msgid "~~~\n" +"def one_year_csv_writer(this_year, all_data, folder_to_save='./', root_name='survey'):\n" +" \"\"\"\n" +" Writes a csv file for data from a given year.\n" +"\n" +" Parameters\n" +" ---------\n" +" this_year : int\n" +" year for which data is extracted\n" +" all_data: pd.DataFrame\n" +" DataFrame with multi-year data\n" +" folder_to_save : str\n" +" folder to save the data files\n" +" root_name: str\n" +" root of the filenames to save the data\n" +" \"\"\"\n" +"\n" +" # Select data for the year\n" +" surveys_year = all_data[all_data.year == this_year]\n" +"\n" +" # Write the new DataFrame to a csv file\n" +" filename = os.path.join(folder_to_save, ''.join([root_name, str(this_year), '.csv']))\n" +" surveys_year.to_csv(filename)\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:660 +# unordered list +msgid "* Modify the functions so that they do not create yearly files if there is no data for a given year" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:661 +msgid "and display an alert to the user (Hint: use `for` loops and conditional statements to do this. For\n" +"an extra challenge, use `try` statements!)" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:664 +# code block +msgid "~~~\n" +" # Write the new DataFrame to a csv file\n" +" if len(surveys_year) > 0:\n" +" filename = os.path.join(folder_to_save, ''.join([root_name, str(this_year), '.csv']))\n" +" surveys_year.to_csv(filename)\n" +" else:\n" +" print(\"No data for year \" + str(this_year))\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:674 +# unordered list +msgid "* The code that you have written so far to loop through the years is good, however, it is not" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:675 +msgid "necessarily reproducible with different datasets. For instance, what happens to the code if we\n" +"have additional years of data in our CSV files? Using the tools that you learned in the previous\n" +"activities, make a list of all years represented in the data. Then create a loop to process your\n" +"data, that begins at the earliest year and ends at the latest year using that list." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:680 +# code block +msgid "~~~\n" +"def yearly_data_csv_writer(all_data, yearcolumn=\"year\",\n" +" folder_to_save='./', root_name='survey'):\n" +" \"\"\"\n" +" Writes separate csv files for each year of data.\n" +"\n" +" all_data --- DataFrame with multi-year data\n" +" yearcolumn --- column name containing the year of the data\n" +" folder_to_save --- folder name to store files\n" +" root_name --- start of the file names stored\n" +" \"\"\"\n" +" years = all_data[\"year\"].unique()\n" +"\n" +" # \"end_year\" is the last year of data we want to pull, so we loop to end_year+1\n" +" filenames = []\n" +" for year in years:\n" +" filenames.append(one_year_csv_writer(year, all_data, folder_to_save, root_name))\n" +" return filenames\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:701 +# header +msgid "## 07-visualization-ggplot-python" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:703 +msgid "If the students have trouble generating the output, or anything happens with that, there is a file\n" +"called \"sample output\" that contains the data file they should have generated in lesson 3." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:706 +msgid "iPython notebooks for plotting can be viewed in the `_extras` folder" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:708 +# header +msgid "## 08-putting-it-all-together" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:710 +msgid "Scientists often operate on mathematical equations. Being able to use them in their graphics has a\n" +"lot of added value. Luckily, Matplotlib provides powerful tools for text control. One of them is the\n" +"ability to use LaTeX mathematical notation, whenever text is used (you can learn more about LaTeX\n" +"math notation here: ). To use mathematical\n" +"notation, surround your text using the dollar sign (\"$\"). LaTeX uses the backslash character (\"\\\\\")\n" +"a lot. Since backslash has a special meaning in the Python strings, you should replace all the\n" +"LaTeX-related backslashes with two backslashes." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:718 +# code block +msgid "~~~\n" +"plt.plot(t, t, 'r--', label='$y=x$')\n" +"plt.plot(t, t**2 , 'bs-', label='$y=x^2$')\n" +"plt.plot(t, (t - 5)**2 + 5 * t - 0.5, 'g^:', label='$y=(x - 5)^2 + 5 x - \\\\frac{1}{2}$') # note the double backslash\n" +"\n" +"plt.legend(loc='upper left', shadow=True, fontsize='x-large')\n" +"\n" +"# Note the double backslashes in the line below.\n" +"plt.xlabel('This is the x axis. It can also contain math such as $\\\\bar{x}=\\\\frac{\\\\sum_{i=1}^{n} {x}} {N}$')\n" +"plt.ylabel('This is the y axis')\n" +"plt.title('This is the figure title')\n" +"\n" +"plt.show()\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:734 +# header +msgid "## 09-working-with-sql" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:736 +msgid "FIXME" +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:739 +msgid "[This page][matplotlib-mathtext] contains more information." +msgstr "" + +#: python-ecology-lesson/_extras/guide.md:741 +msgid "[seaborn]: https://stanford.edu/~mwaskom/software/seaborn\n" +"[altair]: https://github.com/ellisonbg/altair\n" +"[matplotlib-mathtext]: https://matplotlib.org/users/mathtext.html" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:1 +# Front Matter +msgid "---\n" +"layout: page\n" +"title: \"Overview of Jupyter Notebooks\"\n" +"permalink: /jupyter_notebooks/\n" +"---" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:7 +msgid "![Example Jupyter Notebook](../fig/00_0_jupyter_notebook_example.jpg)\n" +"*Screenshot of a [Jupyter Notebook on quantum mechanics](https://github.com/jrjohansson/qutip-lectures) by Robert Johansson*" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:10 +# header +msgid "### How the Jupyter notebook works" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:12 +msgid "After typing the command `jupyter notebook`, the following happens:" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:14 +# unordered list +msgid "* A Jupyter Notebook server is automatically created on your local machine." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:15 +# unordered list +msgid "* The Jupyter Notebook server runs locally on your machine only and does not" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:16 +msgid " use an internet connection.\n" +"* The Jupyter Notebook server opens the Jupyter notebook client, also known\n" +" as the notebook user interface, in your default web browser." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:20 +msgid " ![Jupyter notebook file browser](../fig/00_1_jupyter_file_browser.png)\n" +" *The Jupyter notebook file browser*" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:23 +# unordered list +msgid "* To create a new Python notebook select the \"New\" dropdown on the upper" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:24 +msgid " right of the screen." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:26 +msgid " ![Jupyter notebook file browser](../fig/00_2_jupyter_new_notebook.png)\n" +" *The Jupyter notebook file browser*" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:29 +# unordered list +msgid "* When you can create a new notebook and type code into the browser, the web" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:30 +msgid " browser and the Jupyter notebook server communicate with each other." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:32 +msgid " ![new Jupyter notebook](../fig/00_3_jupyter_blank_notebook.png)\n" +" *A new, blank Jupyter notebook*" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:35 +# unordered list +msgid "* Under the \"help\" menu, take a quick interactive tour of how to" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:36 +msgid " use the notebook. Help on Jupyter and key workshop packages is\n" +" available here too." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:39 +msgid " ![Jupyter tour and help](../fig/00_4_jupyter_tour_help.png)\n" +" *User interface tour and Help*" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:42 +# unordered list +msgid "* The Jupyter Notebook server does the work and calculations, and the web" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:43 +msgid " browser renders the notebook.\n" +"* The web browser then displays the updated notebook to you." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:46 +# unordered list +msgid "* For example, click in the first cell and type some Python code." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:48 +msgid " ![Code cell](../fig/00_5_jupyter_code_before.png)\n" +" *A Code cell*" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:51 +# unordered list +msgid "* This is a **Code** cell (see the cell type dropdown with the word **Code**)." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:52 +msgid " To run the cell, type Shift+Return." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:54 +msgid " ![Code cell and its output](../fig/00_6_jupyter_code_after.png)\n" +" *A Code cell and its output*" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:57 +# unordered list +msgid "* Let's look at a **Markdown** cell. Markdown is a text manipulation" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:58 +msgid " language that is readable yet offers additional formatting. Don't forget\n" +" to select **Markdown** from the cell type dropdown. Click in the cell and\n" +" enter the markdown text." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:62 +msgid " ![markdown input cell](../fig/00_7_jupyter_markdown_before.png)\n" +" *A markdown input cell*" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:65 +# unordered list +msgid "* To run the cell, type Shift+Return." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:67 +msgid " ![rendered markdown cell](../fig/00_8_jupyter_markdown_after.png)\n" +" *A rendered markdown cell*" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:71 +msgid "This workflow has several advantages:" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:73 +# unordered list +msgid "- You can easily type, edit, and copy and paste blocks of code." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:74 +# unordered list +msgid "- Tab completion allows you to easily access the names of things you are using" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:75 +msgid " and learn more about them.\n" +"- It allows you to annotate your code with links, different sized text,\n" +" bullets, etc. to make information more accessible to you and your\n" +" collaborators.\n" +"- It allows you to display figures next to the code that produces them\n" +" to tell a complete story of the analysis." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:82 +# header +msgid "### How the notebook is stored" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:84 +# unordered list +msgid "* The notebook file is stored in a format called JSON and has the suffix" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:85 +msgid " `.ipynb`.\n" +"* Just like HTML for a webpage, what's saved in a notebook file looks\n" +" different from what you see in your browser.\n" +"* But this format allows Jupyter to mix software (in several languages) with\n" +" documentation and graphics, all in one file." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:91 +# header +msgid "### Notebook modes: Control and Edit" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:93 +msgid "The notebook has two modes of operation: Control and Edit. Control mode lets\n" +"you edit notebook level features; while, Edit mode lets you change the\n" +"contents of a notebook cell. Remember a notebook is made up of a number of\n" +"cells which can contain code, markdown, html, visualizations, and more." +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:98 +# header +msgid "### Help and more information" +msgstr "" + +#: python-ecology-lesson/_extras/jupyter_notebooks.md:100 +msgid "Use the **Help** menu and its options when needed." +msgstr "" + +#: python-ecology-lesson/aio.md:1 +# Front Matter +msgid "---\n" +"layout: page\n" +"permalink: /aio/\n" +"---" +msgstr "" + +#: python-ecology-lesson/aio.md:8 +# inline html +msgid "" +msgstr "" + +#: python-ecology-lesson/aio.md:34 +msgid "{% comment %}\n" +"Create an anchor for every episode.\n" +"{% endcomment %}\n" +"{% for episode in site.episodes %}\n" +"
\n" +"{% endfor %}" +msgstr "" + +#: python-ecology-lesson/index.md:1 +# Front Matter +msgid "---\n" +"layout: lesson\n" +"root: .\n" +"\n" +"maintainers:\n" +" - April Wright\n" +" - Tania Allard\n" +" - Maxim Belkin\n" +"---" +msgstr "" + +#: python-ecology-lesson/index.md:11 +msgid "**Lesson Maintainers:** {{ page.maintainers | join: ', ' }}" +msgstr "" + +#: python-ecology-lesson/index.md:13 +msgid "Python is a general purpose programming language that is useful for writing scripts to work effectively and reproducibly with data." +msgstr "" + +#: python-ecology-lesson/index.md:15 +msgid "This is an introduction to Python designed for participants with no programming experience. These lessons can be taught in a day (~ 6 hours). They start with some basic information about Python syntax, the Jupyter notebook interface, and move through how to import CSV files, using the pandas package to work with data frames, how to calculate summary information from a data frame, and a brief introduction to plotting. The last lesson demonstrates how to work with databases directly from Python." +msgstr "" + +#: python-ecology-lesson/index.md:17 +# blockquote, which can be cascaded +msgid "> ## Getting Started" +msgstr "" + +#: python-ecology-lesson/index.md:18 +msgid ">\n" +"> Data Carpentry's teaching is hands-on, so participants are encouraged to use\n" +"> their own computers to ensure the proper setup of tools for an efficient\n" +"> workflow.
**These lessons assume no prior knowledge of the skills or tools.**\n" +">\n" +"> To get started, follow the directions in the \"[Setup][lesson-setup]\" tab to\n" +"> download data to your computer and follow any installation instructions.\n" +">\n" +"> #### Prerequisites\n" +">\n" +"> This lesson requires a working copy of **Python**.\n" +">
To most effectively use these materials, please make sure to install\n" +"> everything *before* working through this lesson." +msgstr "" + +#: python-ecology-lesson/index.md:31 +#: python-ecology-lesson/index.md:36 +#: python-ecology-lesson/setup.md:24 +#: python-ecology-lesson/setup.md:42 +# SC/DC Template label +msgid "{: .prereq}" +msgstr "" + +#: python-ecology-lesson/index.md:33 +# blockquote, which can be cascaded +msgid "> ## For Instructors" +msgstr "" + +#: python-ecology-lesson/index.md:34 +# blockquote, which can be cascaded +msgid "> If you are teaching this lesson in a workshop, please see the" +msgstr "" + +#: python-ecology-lesson/index.md:35 +# blockquote, which can be cascaded +msgid "> [Instructor notes](guide)." +msgstr "" + +#: python-ecology-lesson/reference.md:1 +# Front Matter +msgid "---\n" +"layout: reference\n" +"---" +msgstr "" + +#: python-ecology-lesson/reference.md:5 +# header +msgid "## Glossary" +msgstr "" + +#: python-ecology-lesson/reference.md:7 +msgid "{:auto_ids}\n" +"0-based indexing\n" +": is a way of assigning indices to elements in a sequential, ordered data structure\n" +" starting from 0, i.e. where the first element of the sequence has index 0." +msgstr "" + +#: python-ecology-lesson/reference.md:12 +msgid "CSV (file)\n" +": is an acronym which stands for Comma-Separated Values file. CSV files store\n" +" tabular data, either numbers, strings, or a combination of the two, in plain\n" +" text with columns separated by a comma and rows by the carriage return character." +msgstr "" + +#: python-ecology-lesson/reference.md:17 +msgid "database\n" +": is an organized collection of data." +msgstr "" + +#: python-ecology-lesson/reference.md:20 +msgid "dataframe\n" +": is a two-dimensional labeled data structure with columns of (potentially)\n" +" different type." +msgstr "" + +#: python-ecology-lesson/reference.md:24 +msgid "data structure\n" +": is a particular way of organizing data in memory." +msgstr "" + +#: python-ecology-lesson/reference.md:27 +msgid "data type\n" +": is a particular kind of item that can be assigned to a variable, defined by\n" +" by the values it can take, the programming language in use and the operations\n" +" that can be performed on it." +msgstr "" + +#: python-ecology-lesson/reference.md:32 +msgid "dictionary\n" +": is an unordered Python data structure designed to contain key-value pairs, where both\n" +" the key and the value can be integers, floats or strings. Elements of a dictionary\n" +" can be accessed by their key and can be modified." +msgstr "" + +#: python-ecology-lesson/reference.md:37 +msgid "docstring\n" +": is an optional documentation string to describe what a Python function does." +msgstr "" + +#: python-ecology-lesson/reference.md:40 +msgid "faceting\n" +": is the act of plotting relationships between set variables in multiple subsets\n" +" of the data with the results appearing as different panels in the same figure." +msgstr "" + +#: python-ecology-lesson/reference.md:44 +msgid "float\n" +": is a Python data type designed to store positive and negative decimal numbers\n" +" by means of a floating point representation." +msgstr "" + +#: python-ecology-lesson/reference.md:48 +msgid "function\n" +": is a group of related statements that perform a specific task." +msgstr "" + +#: python-ecology-lesson/reference.md:51 +msgid "integer\n" +": is a Python data type designed to store positive and negative integer numbers." +msgstr "" + +#: python-ecology-lesson/reference.md:54 +msgid "interactive mode\n" +": is an online mode of operation in which the user writes the commands directly\n" +" on the command line one-by-one and execute them immediately by pressing a button\n" +" on the keyword, usually Return." +msgstr "" + +#: python-ecology-lesson/reference.md:59 +msgid "join key\n" +": is a variable or an array representing the column names over which pandas.DataFrame.join()\n" +" merge together columns of different data sets." +msgstr "" + +#: python-ecology-lesson/reference.md:63 +msgid "library\n" +": is a set of functions and methods grouped together to perform some specific\n" +" sort of tasks." +msgstr "" + +#: python-ecology-lesson/reference.md:67 +msgid "list\n" +": is a Python data structure designed to contain sequences of integers, floats,\n" +" strings and any combination of the previous. The sequence is ordered and indexed\n" +" by integers, starting from 0. Elements of a list can be accessed by their index\n" +" and can be modified." +msgstr "" + +#: python-ecology-lesson/reference.md:73 +msgid "loop\n" +": is a sequence of instructions that is continually repeated until a condition\n" +" is satisfied." +msgstr "" + +#: python-ecology-lesson/reference.md:77 +msgid "NaN\n" +": is an acronym for Not-a-Number and represents that either a value is missing or\n" +" the calculation cannot output any meaningful result." +msgstr "" + +#: python-ecology-lesson/reference.md:81 +msgid "None\n" +": is an object that represents no value." +msgstr "" + +#: python-ecology-lesson/reference.md:84 +msgid "scripting mode\n" +": is an offline mode of operation in which the user writes the commands to be\n" +" executed in a text file (with .py extension for Python) which is then compiled\n" +" or interpreted to run the program. Notes that Python interprets script on\n" +" run-time and compiles a binary version of the program to speed up the execution time." +msgstr "" + +#: python-ecology-lesson/reference.md:90 +msgid "Sequential (data structure)\n" +": is an ordered group of objects stored in memory which can be accessed specifying\n" +" their index, i.e. their position, in the structure." +msgstr "" + +#: python-ecology-lesson/reference.md:94 +msgid "SQL\n" +": or Structured Query Language, is a domain-specific language for managing data\n" +" stored in a relational database management system (RDBMS)." +msgstr "" + +#: python-ecology-lesson/reference.md:98 +msgid "SQLite\n" +": is a self-contained, public domain SQL database engine." +msgstr "" + +#: python-ecology-lesson/reference.md:101 +msgid "string\n" +": is a Python data type designed to store sequences of characters." +msgstr "" + +#: python-ecology-lesson/reference.md:104 +msgid "tuple\n" +": is a Python data structure designed to contain sequences of integers, floats,\n" +" strings and any combination of the previous. The sequence is ordered and indexed\n" +" by integers, starting from 0. Elements of a tuple can be accessed by their index\n" +" but cannot be modified." +msgstr "" + +#: python-ecology-lesson/setup.md:1 +# Front Matter +msgid "---\n" +"layout: page\n" +"title: Setup\n" +"---" +msgstr "" + +#: python-ecology-lesson/setup.md:6 +# blockquote, which can be cascaded +msgid "> ## Data" +msgstr "" + +#: python-ecology-lesson/setup.md:7 +# blockquote, which can be cascaded +msgid "> Data for this lesson is from the Portal Project Teaching Database -" +msgstr "" + +#: python-ecology-lesson/setup.md:8 +# blockquote, which can be cascaded +msgid "> [available on FigShare](https://figshare.com/articles/Portal_Project_Teaching_Database/1314459)." +msgstr "" + +#: python-ecology-lesson/setup.md:9 +msgid ">\n" +"> We will use the six files listed below for the data in this lesson.\n" +"> Download these files to your computer either by clicking\n" +"> [this link](https://github.com/weecology/portal-teachingdb/archive/master.zip),\n" +"> which will give you everything in a single compressed file.\n" +"> You'll need to unzip this file after downloading it.\n" +">\n" +"> Or download each file indvidually with the following links:\n" +">\n" +"> - [surveys.csv](https://ndownloader.figshare.com/files/10717177)\n" +"> - [species.csv](https://ndownloader.figshare.com/files/3299483)\n" +"> - [speciesSubset.csv]({{ page.root }}/data/speciesSubset.csv)\n" +"> - [plots.csv](https://ndownloader.figshare.com/files/3299474)\n" +"> - [bouldercreek_09_2013.txt]({{ page.root }}/data/bouldercreek_09_2013.txt)\n" +"> - [SQL Database](https://ndownloader.figshare.com/files/11188550)" +msgstr "" + +#: python-ecology-lesson/setup.md:28 +# blockquote, which can be cascaded +msgid "> ## Software" +msgstr "" + +#: python-ecology-lesson/setup.md:29 +# blockquote, which can be cascaded +msgid "> [Python](http://python.org) is a popular language for" +msgstr "" + +#: python-ecology-lesson/setup.md:30 +# blockquote, which can be cascaded +msgid "> scientific computing, and great for general-purpose programming as" +msgstr "" + +#: python-ecology-lesson/setup.md:31 +# blockquote, which can be cascaded +msgid "> well. Installing all of its scientific packages individually can be" +msgstr "" + +#: python-ecology-lesson/setup.md:32 +# blockquote, which can be cascaded +msgid "> a bit difficult, so we recommend an all-in-one installer." +msgstr "" + +#: python-ecology-lesson/setup.md:33 +msgid ">\n" +"> For this workshop we use Python version 3.x.\n" +">\n" +"> ### Required Python Packages for this workshop\n" +">\n" +"> * [Pandas](http://pandas.pydata.org/)\n" +"> * [Jupyter notebook](http://jupyter.org/)\n" +"> * [Numpy](http://www.numpy.org/)\n" +"> * [Matplotlib](http://matplotlib.org/)" +msgstr "" + +#: python-ecology-lesson/setup.md:44 +# header +msgid "## Install the workshop packages" +msgstr "" + +#: python-ecology-lesson/setup.md:46 +msgid "For installing these packages we will use Anaconda or Miniconda.\n" +"They both use [Conda](http://conda.pydata.org/docs/), the main difference is\n" +"that Anaconda comes with a lot of packages pre-installed.\n" +"With Miniconda you will need to install the required packages." +msgstr "" + +#: python-ecology-lesson/setup.md:51 +# header +msgid "### Anaconda installation" +msgstr "" + +#: python-ecology-lesson/setup.md:53 +msgid "Anaconda will install the workshop packages for you." +msgstr "" + +#: python-ecology-lesson/setup.md:55 +# header +msgid "#### Download and install Anaconda" +msgstr "" + +#: python-ecology-lesson/setup.md:57 +msgid "Download and install [Anaconda](https://www.anaconda.com/distribution/#download-section).\n" +"Remember to download and install the installer for Python 3.x." +msgstr "" + +#: python-ecology-lesson/setup.md:60 +# header +msgid "#### Download plotting package" +msgstr "" + +#: python-ecology-lesson/setup.md:62 +msgid "The plotting package plotnine is not installed by default. From the terminal,\n" +"type:" +msgstr "" + +#: python-ecology-lesson/setup.md:65 +# code block +msgid "~~~\n" +"conda install -c conda-forge plotnine\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/setup.md:70 +# header +msgid "### Miniconda installation" +msgstr "" + +#: python-ecology-lesson/setup.md:72 +msgid "Miniconda is a \"light\" version of Anaconda. If you install and use Miniconda\n" +"you will also need to install the workshop packages." +msgstr "" + +#: python-ecology-lesson/setup.md:75 +# header +msgid "#### Download and install Miniconda" +msgstr "" + +#: python-ecology-lesson/setup.md:77 +msgid "Download and install [Miniconda](https://docs.conda.io/en/latest/miniconda.html)\n" +"following the instructions. Remember to download and run the installer for\n" +"Python 3.x." +msgstr "" + +#: python-ecology-lesson/setup.md:81 +# header +msgid "#### Check the installation of Miniconda" +msgstr "" + +#: python-ecology-lesson/setup.md:83 +#: python-ecology-lesson/setup.md:92 +msgid "From the terminal, type:" +msgstr "" + +#: python-ecology-lesson/setup.md:85 +# code block +msgid "~~~\n" +"conda list\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/setup.md:90 +# header +msgid "### Install the required workshop packages with conda" +msgstr "" + +#: python-ecology-lesson/setup.md:94 +# code block +msgid "~~~\n" +"conda install -y numpy pandas matplotlib jupyter\n" +"conda install -c conda-forge plotnine\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/setup.md:100 +# header +msgid "## Launch a Jupyter notebook" +msgstr "" + +#: python-ecology-lesson/setup.md:102 +msgid "After installing either Anaconda or Miniconda and the workshop packages,\n" +"launch a Jupyter notebook by typing this command from the terminal:" +msgstr "" + +#: python-ecology-lesson/setup.md:105 +# code block +msgid "~~~\n" +"jupyter notebook\n" +"~~~" +msgstr "" + +#: python-ecology-lesson/setup.md:110 +msgid "The notebook should open automatically in your browser. If it does not or you\n" +"wish to use a different browser, open this link: ." +msgstr "" + +#: python-ecology-lesson/setup.md:113 +msgid "For a bried introduction to Jupyter Notebooks, please consult with our\n" +"[Introduction to Jupyter Notebooks](jupyter_notebooks) page." +msgstr "" + diff --git a/po/shell-novice.es.po b/po/shell-novice.es.po new file mode 100644 index 00000000..87742d17 --- /dev/null +++ b/po/shell-novice.es.po @@ -0,0 +1,9545 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Traductor espanol , 2018. +# +# +msgid "" +msgstr "" +"Project-Id-Version: i18n\n" +"Report-Msgid-Bugs-To: https://github.com/haiwen/seafile-docs/issues\n" +"POT-Creation-Date: 2018-03-28 00:55:36+0100\n" +"PO-Revision-Date: 2018-03-28 11:09+0100\n" +"Last-Translator: Traductor espanol \n" +"Language: es \n" +"Language-Team: Es \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Gtranslator 2.91.7\n" + +# Front Matter +#: shell-novice/CONDUCT.md:1 +msgid "" +"---\n" +"layout: page\n" +"title: \"Contributor Code of Conduct\"\n" +"permalink: /conduct/\n" +"---" +msgstr "" +"---\n" +"layout: page\n" +"title: \"Código de conducta del contribuidor\"\n" +"permalink: /conduct/\n" +"---" + +#: shell-novice/CONDUCT.md:6 +msgid "" +"As contributors and maintainers of this project,\n" +"we pledge to respect all people who contribute through reporting issues,\n" +"posting feature requests,\n" +"updating documentation,\n" +"submitting pull requests or patches,\n" +"and other activities." +msgstr "" +"Los contribuidores y **maintainers** de este proyecto,\n" +"nos comprometemos a respetar a todas las personas que contribuyen a través " +"de problemas de informes **issues**,\n" +"publicar solicitudes de mejora,\n" +"actualizar la documentación,\n" +"enviando solicitudes de mejoras o parches,\n" +"y otras actividades." + +#: shell-novice/CONDUCT.md:13 +msgid "" +"We are committed to making participation in this project a harassment-free " +"experience for everyone,\n" +"regardless of level of experience,\n" +"gender,\n" +"gender identity and expression,\n" +"sexual orientation,\n" +"disability,\n" +"personal appearance,\n" +"body size,\n" +"race,\n" +"ethnicity,\n" +"age,\n" +"or religion." +msgstr "" +"Nos comprometemos a hacer que la participación en este proyecto sea una " +"experiencia libre de acoso para todos,\n" +"independientemente del nivel de experiencia,\n" +"género,\n" +"identidad y expresión de género,\n" +"orientación sexual,\n" +"discapacidad,\n" +"apariencia personal,\n" +"tamaño corporal,\n" +"carrera,\n" +"etnia,\n" +"años,\n" +"o religión." + +#: shell-novice/CONDUCT.md:26 +msgid "" +"Examples of unacceptable behavior by participants include the use of sexual " +"language or imagery,\n" +"derogatory comments or personal attacks,\n" +"trolling,\n" +"public or private harassment,\n" +"insults,\n" +"or other unprofessional conduct." +msgstr "" +"Los ejemplos de comportamiento inaceptable de los participantes incluyen el " +"uso de imágenes o lenguaje sexual,\n" +"comentarios despectivos o ataques personales,\n" +"trolling,\n" +"acoso público o privado,\n" +"insultos,\n" +"u otra conducta no profesional." + +#: shell-novice/CONDUCT.md:33 +msgid "" +"Project maintainers have the right and responsibility to remove, edit, or " +"reject\n" +"comments, commits, code, wiki edits, issues, and other contributions\n" +"that are not aligned to our [Code of Conduct][coc].\n" +"Project maintainers who do not follow the Code of Conduct may be removed " +"from the project team." +msgstr "" +"Los mantenedores de proyectos tienen el derecho y la responsabilidad de " +"eliminar, editar o rechazar\n" +"comentarios, **commits**, código, ediciones de wiki, problemas y otras " +"contribuciones\n" +"que no estén alineados con nuestro [Código de Conducta][coc].\n" +"Los **maintainers** del proyecto que no sigan el Código de Conducta pueden " +"ser removidos del equipo del proyecto." + +#: shell-novice/CONDUCT.md:38 +msgid "" +"Instances of abusive, harassing, or otherwise unacceptable behavior\n" +"may be reported by following our [reporting guidelines][coc-reporting]." +msgstr "" +"Instancias de comportamiento abusivo, acosador o de otra manera inaceptable\n" +"puede informarse siguiendo nuestras [guías de informes][coc-reporting]." + +# unordered list +#: shell-novice/CONDUCT.md:42 +msgid "- [Software and Data Carpentry Code of Conduct][coc]" +msgstr "- [Código de conducta de Software y Data Carpentry][coc]" + +# unordered list +#: shell-novice/CONDUCT.md:43 +msgid "- [Code of Conduct Reporting Guide][coc-reporting]" +msgstr "- [Guía de informes del código de conducta][coc-reporting]" + +#: shell-novice/CONDUCT.md:45 +msgid "{% include links.md %}" +msgstr "{% include links.md %}" + +# header +#: shell-novice/CONTRIBUTING.md:1 +msgid "# Contributing" +msgstr "{% include links.md %}" + +#: shell-novice/CONTRIBUTING.md:3 +msgid "" +"[Software Carpentry][swc-site] and [Data Carpentry][dc-site] are open source " +"projects,\n" +"and we welcome contributions of all kinds:\n" +"new lessons,\n" +"fixes to existing material,\n" +"bug reports,\n" +"and reviews of proposed changes are all welcome." +msgstr "" +"[Software Carpentry][swc-site] y [Data Carpentry][dc-site] son ​\n" +"proyectos de código abierto, y damos la bienvenida a contribuciones \n" +"de todo tipo: nuevas lecciones, correcciones al material existente, \n" +"informes de errores, y revisiones de los cambios propuestos son todas\n" +"bienvenidas." + +# header +#: shell-novice/CONTRIBUTING.md:10 +msgid "## Contributor Agreement" +msgstr "## Acuerdo de Colaborador" + +#: shell-novice/CONTRIBUTING.md:12 +msgid "" +"By contributing,\n" +"you agree that we may redistribute your work under [our license](LICENSE." +"md).\n" +"In exchange,\n" +"we will address your issues and/or assess your change proposal as promptly " +"as we can,\n" +"and help you become a member of our community.\n" +"Everyone involved in [Software Carpentry][swc-site] and [Data Carpentry][dc-" +"site]\n" +"agrees to abide by our [code of conduct](CONDUCT.md)." +msgstr "" +"Al contribuir, tú aceptas que podemos redistribuir su trabajo bajo\n" +"[nuestra licencia](LICENCIA.md). A cambio, abordaremos tus problemas \n" +"y/o evaluaremos tu propuesta de cambio tan pronto como podamos, y \n" +"te ayudaremos a convertirte en miembro de nuestra comunidad. Todos los \n" +"involucrados en [Software Carpentry][swc-site] y \n" +"[Data Carpentry][dc-site]\n" +"aceptan cumplir con nuestro [código de conducta](CONDUCT.md)." + +# header +#: shell-novice/CONTRIBUTING.md:20 +msgid "## How to Contribute" +msgstr "## Cómo contribuir" + +#: shell-novice/CONTRIBUTING.md:22 +msgid "" +"The easiest way to get started is to file an issue\n" +"to tell us about a spelling mistake,\n" +"some awkward wording,\n" +"or a factual error.\n" +"This is a good way to introduce yourself\n" +"and to meet some of our community members." +msgstr "" +"La forma más fácil de comenzar es presentar un problema para \n" +"poder corregirlo, como un error ortográfico, algunas palabras no claras,\n" +"o un error fáctico. Contribuir es una buena forma de presentarte \n" +"y conocer a algunos de los miembros de nuestra comunidad." + +# ordered list +#: shell-novice/CONTRIBUTING.md:29 +msgid "1. If you do not have a [GitHub][github] account," +msgstr "1. Si no tienes una cuenta de [GitHub][github]," + +#: shell-novice/CONTRIBUTING.md:30 +msgid "" +" you can [send us comments by email][contact].\n" +" However,\n" +" we will be able to respond more quickly if you use one of the other " +"methods described below." +msgstr "" +" puedes [enviarnos comentarios por correo electrónico][contacto].\n" +" Sin embargo, podremos responder más rápidamente si usa uno de los otros " +"métodos que se describen a continuación." + +# ordered list +#: shell-novice/CONTRIBUTING.md:34 +msgid "2. If you have a [GitHub][github] account," +msgstr "2. Si tiene una cuenta de [GitHub][github]," + +#: shell-novice/CONTRIBUTING.md:35 +msgid "" +" or are willing to [create one][github-join],\n" +" but do not know how to use Git,\n" +" you can report problems or suggest improvements by [creating an issue]" +"[issues].\n" +" This allows us to assign the item to someone\n" +" and to respond to it in a threaded discussion." +msgstr "" +" o están dispuestos a [crear una][github-join],\n" +" pero no sabes cómo usar git,\n" +" puedes informar problemas o sugerir mejoras al [crear un problema o " +"**issue**][nuevo-problema].\n" +" Esto nos permite asignar el elemento a alguien\n" +" y responder en una conversación abierta." + +# ordered list +#: shell-novice/CONTRIBUTING.md:41 +msgid "3. If you are comfortable with Git," +msgstr "3. Si te sientes cómodo con Git," + +#: shell-novice/CONTRIBUTING.md:42 +msgid "" +" and would like to add or change material,\n" +" you can submit a pull request (PR).\n" +" Instructions for doing this are [included below](#using-github)." +msgstr "" +" y te gustaría agregar o cambiar material,\n" +" puede enviar una solicitud de extracción o **pull request**(PR).\n" +" Las instrucciones para hacer esto [se incluyen a continuación][como-" +"contribuir]." + +# header +#: shell-novice/CONTRIBUTING.md:46 +msgid "## Where to Contribute" +msgstr "## Donde Contribuir" + +# ordered list +#: shell-novice/CONTRIBUTING.md:48 +msgid "1. If you wish to change this lesson," +msgstr "1. Si deseas cambiar esta lección," + +#: shell-novice/CONTRIBUTING.md:49 +msgid "" +" please work in ,\n" +" which can be viewed at ." +msgstr "" +" por favor trabaja en ,\n" +" que se puede ver en ." + +# ordered list +#: shell-novice/CONTRIBUTING.md:52 +msgid "2. If you wish to change the example lesson," +msgstr "2. Si deseas cambiar la lección de ejemplo," + +#: shell-novice/CONTRIBUTING.md:53 +msgid "" +" please work in ,\n" +" which documents the format of our lessons\n" +" and can be viewed at ." +msgstr "" +" por favor trabaja en ,\n" +" que documenta el formato de nuestras lecciones\n" +" y se puede ver en ." + +# ordered list +#: shell-novice/CONTRIBUTING.md:57 +msgid "3. If you wish to change the template used for workshop websites," +msgstr "" +"3. Si deseas cambiar la plantilla utilizada para los sitios web del taller," + +#: shell-novice/CONTRIBUTING.md:58 +msgid "" +" please work in .\n" +" The home page of that repository explains how to set up workshop " +"websites,\n" +" while the extra pages in \n" +" provide more background on our design choices." +msgstr "" +" por favor trabaja en .\n" +" La página de inicio de ese repositorio explica cómo configurar sitios " +"web de talleres,\n" +" mientras que las páginas adicionales en \n" +" proporcionan más antecedentes sobre nuestras elecciones de diseño." + +# ordered list +#: shell-novice/CONTRIBUTING.md:63 +msgid "4. If you wish to change CSS style files, tools," +msgstr "4. Si deseas cambiar los archivos de estilo CSS, herramientas," + +#: shell-novice/CONTRIBUTING.md:64 +msgid "" +" or HTML boilerplate for lessons or workshops stored in `_includes` or " +"`_layouts`,\n" +" please work in ." +msgstr "" +" o texto estándar HTML para lecciones o talleres almacenados en " +"`_includes` o` _layouts`,\n" +" por favor trabaja en ." + +# header +#: shell-novice/CONTRIBUTING.md:67 +msgid "## What to Contribute" +msgstr "## Qué aportar" + +#: shell-novice/CONTRIBUTING.md:69 +msgid "" +"There are many ways to contribute,\n" +"from writing new exercises and improving existing ones\n" +"to updating or filling in the documentation\n" +"and submitting [bug reports][issues]\n" +"about things that don't work, aren't clear, or are missing.\n" +"If you are looking for ideas,\n" +"please see [the list of issues for this repository][issues],\n" +"or the issues for [Data Carpentry][dc-issues]\n" +"and [Software Carpentry][swc-issues] projects." +msgstr "" +"Hay muchas maneras de contribuir, de escribir nuevos ejercicios y\n" +"mejorar los existentes para actualizar o completar la documentación y\n" +"enviando [informes de error o **issues**][nuevo-problema] sobre cosas que " +"no\n" +"funcionan, no son claras o faltan. Si estás buscando ideas, por favor\n" +"ve [la lista de problemas para este repositorio][issues], o los \n" +"problemas o **issues** para los proyectos de [Data Carpentry][dc-issues] y \n" +"[Software Carpentry][swc-issues]." + +#: shell-novice/CONTRIBUTING.md:79 +msgid "" +"Comments on issues and reviews of pull requests are just as welcome:\n" +"we are smarter together than we are on our own.\n" +"Reviews from novices and newcomers are particularly valuable:\n" +"it's easy for people who have been using these lessons for a while\n" +"to forget how impenetrable some of this material can be,\n" +"so fresh eyes are always welcome." +msgstr "" +"Los comentarios sobre problemas y revisiones de solicitudes de\n" +"extracción son igualmente bienvenidos: somos más fuertes juntos\n" +"que solos, por eso trabajamos en equipo. Los comentarios de principiantes y " +"recién \n" +"llegados son particularmente valiosos: es fácil para las personas\n" +"que han estado usando estas lecciones por un tiempo, olvidar lo \n" +"impenetrable que puede ser parte de este material, por lo que los \n" +"ojos frescos son siempre bienvenidos." + +# header +#: shell-novice/CONTRIBUTING.md:86 +msgid "## What *Not* to Contribute" +msgstr "## Qué *No* contribuir" + +#: shell-novice/CONTRIBUTING.md:88 +msgid "" +"Our lessons already contain more material than we can cover in a typical " +"workshop,\n" +"so we are usually *not* looking for more concepts or tools to add to them.\n" +"As a rule,\n" +"if you want to introduce a new idea,\n" +"you must (a) estimate how long it will take to teach\n" +"and (b) explain what you would take out to make room for it.\n" +"The first encourages contributors to be honest about requirements;\n" +"the second, to think hard about priorities." +msgstr "" +"Nuestras lecciones ya contienen más material de lo que podemos cubrir\n" +"en un taller típico, por lo que usualmente *no* buscamos más \n" +"conceptos o herramientas para agregar. Como una regla, si quieres\n" +"presentar una nueva idea, debes (a) estimar cuánto tiempo llevará \n" +"enseñar y (b) explicar lo que sacaría para darle espacio al nuevo concepto. " +"El primero\n" +"alienta a los contribuyentes a ser honestos acerca de los requisitos;\n" +"el segundo, pensar mucho sobre las prioridades." + +#: shell-novice/CONTRIBUTING.md:97 +msgid "" +"We are also not looking for exercises or other material that only run on one " +"platform.\n" +"Our workshops typically contain a mixture of Windows, Mac OS X, and Linux " +"users;\n" +"in order to be usable,\n" +"our lessons must run equally well on all three." +msgstr "" +"Tampoco buscamos ejercicios u otro material que sólo se ejecute en \n" +"una plataforma. Nuestros talleres suelen contener una mezcla de \n" +"usuarios de Windows, Mac OS X y Linux; para ser utilizable, nuestras \n" +"lecciones deben correr igualmente bien en las tres plataformas." + +# header +#: shell-novice/CONTRIBUTING.md:102 +msgid "## Using GitHub" +msgstr "## Usando GitHub" + +#: shell-novice/CONTRIBUTING.md:104 +msgid "" +"If you choose to contribute via GitHub,\n" +"you may want to look at\n" +"[How to Contribute to an Open Source Project on GitHub][how-contribute].\n" +"In brief:" +msgstr "" +"Si eliges contribuir a través de GitHub, es posible que desees mirar\n" +"[Cómo contribuir a un proyecto de código abierto en GitHub][como-" +"contribuir].\n" +"En breve:" + +# ordered list +#: shell-novice/CONTRIBUTING.md:109 +msgid "" +"1. The published copy of the lesson is in the `gh-pages` branch of the " +"repository" +msgstr "" +"1. La copia publicada de la lección está en la rama `gh-pages` del " +"repositorio" + +#: shell-novice/CONTRIBUTING.md:110 +msgid "" +" (so that GitHub will regenerate it automatically).\n" +" Please create all branches from that,\n" +" and merge the [master repository][repo]'s `gh-pages` branch into your " +"`gh-pages` branch\n" +" before starting work.\n" +" Please do *not* work directly in your `gh-pages` branch,\n" +" since that will make it difficult for you to work on other contributions." +msgstr "" +" (para que GitHub lo regenere automáticamente).\n" +" Por favor crea todas las ramas de eso,\n" +" y fusiona la rama `gh-pages` de [repositorio maestro][repo] en la rama` " +"gh-pages`\n" +" antes de comenzar a trabajar.\n" +" Por favor, *no* trabajes directamente en tu rama `gh-pages`,\n" +" ya que esto te dificultará trabajar en otras contribuciones." + +# ordered list +#: shell-novice/CONTRIBUTING.md:117 +msgid "2. We use [GitHub flow][github-flow] to manage changes:" +msgstr "2. Usamos [GitHub flow][github-flow] para gestionar los cambios:" + +#: shell-novice/CONTRIBUTING.md:118 +msgid "" +" 1. Create a new branch in your desktop copy of this repository for each " +"significant change.\n" +" 2. Commit the change in that branch.\n" +" 3. Push that branch to your fork of this repository on GitHub.\n" +" 4. Submit a pull request from that branch to the [master repository]" +"[repo].\n" +" 5. If you receive feedback,\n" +" make changes on your desktop and push to your branch on GitHub:\n" +" the pull request will update automatically." +msgstr "" +" 1. Crea una nueva rama en su copia de escritorio de este repositorio " +"para cada cambio significativo.\n" +" 2. **Commit** el cambio en esa rama.\n" +" 3. **Push** esa rama a su **fork** de este repositorio en GitHub.\n" +" 4. Envía una solicitud de extracción **Pull request** desde esa rama al " +"[repositorio principal][repo].\n" +" 5. Si recibes comentarios,\n" +" hacer cambios en tu escritorio y enviar a GitHub:\n" +" la solicitud de extracción se actualizará automáticamente." + +#: shell-novice/CONTRIBUTING.md:126 +msgid "" +"Each lesson has two maintainers who review issues and pull requests\n" +"or encourage others to do so.\n" +"The maintainers are community volunteers,\n" +"and have final say over what gets merged into the lesson." +msgstr "" +"Cada lección tiene dos mantenedores que revisan problemas y solicitan \n" +"extracción o alentan a otros a hacerlo. Los mantenedores son \n" +"voluntarios de la comunidad, y tienen una opinión final sobre lo que \n" +"se fusiona en la lección." + +# header +#: shell-novice/CONTRIBUTING.md:131 +msgid "## Other Resources" +msgstr "## Otros recursos" + +#: shell-novice/CONTRIBUTING.md:133 +msgid "" +"General discussion of [Software Carpentry][swc-site] and [Data Carpentry][dc-" +"site]\n" +"happens on the [discussion mailing list][discuss-list],\n" +"which everyone is welcome to join.\n" +"You can also [reach us by email][contact]." +msgstr "" +"Discusión general de [Software Carpentry][swc-site] y \n" +"[Data Carpentry][dc-site] sucede en la \n" +"[lista de distribución de discusiones][discuss-list], \n" +"a la cual todos son bienvenidos. También puedes \n" +"[contactarnos por correo electrónico][contacto]." + +#: shell-novice/CONTRIBUTING.md:138 +msgid "" +"[contact]: mailto:admin@software-carpentry.org\n" +"[dc-issues]: https://github.com/issues?q=user%3Adatacarpentry\n" +"[dc-lessons]: http://datacarpentry.org/lessons/\n" +"[dc-site]: http://datacarpentry.org/\n" +"[discuss-list]: http://lists.software-carpentry.org/listinfo/discuss\n" +"[github]: http://github.com\n" +"[github-flow]: https://guides.github.com/introduction/flow/\n" +"[github-join]: https://github.com/join\n" +"[how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-" +"source-project-on-github\n" +"[issues]: https://github.com/swcarpentry/shell-novice/issues/\n" +"[repo]: https://github.com/swcarpentry/shell-novice/\n" +"[swc-issues]: https://github.com/issues?q=user%3Aswcarpentry\n" +"[swc-lessons]: http://software-carpentry.org/lessons/\n" +"[swc-site]: http://software-carpentry.org/" +msgstr "" +"[contacto]: mailto:admin@software-carpentry.org\n" +"[dc-issues]: https://github.com/issues?q=user%3Adatacarpentry\n" +"[dc-lessons]: http://datacarpentry.org/lessons/\n" +"[dc-site]: http://datacarpentry.org/\n" +"[discuss-list]: http://lists.software-carpentry.org/listinfo/discuss\n" +"[github]: http://github.com\n" +"[github-flow]: https://guides.github.com/introduction/flow/\n" +"[github-join]: https://github.com/join\n" +"[como-contribuir]: https://egghead.io/series/how-to-contribute-to-an-open-" +"source-project-on-github\n" +"[nuevo-problema]: https://github.com/swcarpentry/shell-novice-es/issues/new\n" +"[issues]: https://github.com/swcarpentry/shell-novice-es/issues/\n" +"[repo]: https://github.com/swcarpentry/shell-novice-es/\n" +"[swc-issues]: https://github.com/issues?q=user%3Aswcarpentry\n" +"[swc-lessons]: http://software-carpentry.org/lessons/\n" +"[swc-site]: http://software-carpentry.org/" + +# Front Matter +#: shell-novice/LICENSE.md:1 +msgid "" +"---\n" +"layout: page\n" +"title: \"Licenses\"\n" +"root: .\n" +"---" +msgstr "" + +# header +#: shell-novice/LICENSE.md:6 +msgid "## Instructional Material" +msgstr "" + +#: shell-novice/LICENSE.md:8 +msgid "" +"All Software Carpentry and Data Carpentry instructional material is\n" +"made available under the [Creative Commons Attribution\n" +"license][cc-by-human]. The following is a human-readable summary of\n" +"(and not a substitute for) the [full legal text of the CC BY 4.0\n" +"license][cc-by-legal]." +msgstr "" + +#: shell-novice/LICENSE.md:14 +msgid "You are free:" +msgstr "" + +# unordered list +#: shell-novice/LICENSE.md:16 +msgid "" +"* to **Share**---copy and redistribute the material in any medium or format" +msgstr "" + +# unordered list +#: shell-novice/LICENSE.md:17 +msgid "* to **Adapt**---remix, transform, and build upon the material" +msgstr "" + +#: shell-novice/LICENSE.md:19 +msgid "for any purpose, even commercially." +msgstr "" + +#: shell-novice/LICENSE.md:21 +msgid "" +"The licensor cannot revoke these freedoms as long as you follow the\n" +"license terms." +msgstr "" + +#: shell-novice/LICENSE.md:24 +msgid "Under the following terms:" +msgstr "" + +# unordered list +#: shell-novice/LICENSE.md:26 +msgid "* **Attribution**---You must give appropriate credit (mentioning that" +msgstr "" + +#: shell-novice/LICENSE.md:27 +msgid "" +" your work is derived from work that is Copyright © Software\n" +" Carpentry and, where practical, linking to\n" +" http://software-carpentry.org/), provide a [link to the\n" +" license][cc-by-human], and indicate if changes were made. You may do\n" +" so in any reasonable manner, but not in any way that suggests the\n" +" licensor endorses you or your use." +msgstr "" + +#: shell-novice/LICENSE.md:34 +msgid "" +"**No additional restrictions**---You may not apply legal terms or\n" +"technological measures that legally restrict others from doing\n" +"anything the license permits. With the understanding that:" +msgstr "" + +#: shell-novice/LICENSE.md:38 +msgid "Notices:" +msgstr "" + +# unordered list +#: shell-novice/LICENSE.md:40 +msgid "* You do not have to comply with the license for elements of the" +msgstr "" + +#: shell-novice/LICENSE.md:41 +msgid "" +" material in the public domain or where your use is permitted by an\n" +" applicable exception or limitation.\n" +"* No warranties are given. The license may not give you all of the\n" +" permissions necessary for your intended use. For example, other\n" +" rights such as publicity, privacy, or moral rights may limit how you\n" +" use the material." +msgstr "" + +# header +#: shell-novice/LICENSE.md:48 +msgid "## Software" +msgstr "" + +#: shell-novice/LICENSE.md:50 +msgid "" +"Except where otherwise noted, the example programs and other software\n" +"provided by Software Carpentry and Data Carpentry are made available under " +"the\n" +"[OSI][osi]-approved\n" +"[MIT license][mit-license]." +msgstr "" + +#: shell-novice/LICENSE.md:55 +msgid "" +"Permission is hereby granted, free of charge, to any person obtaining\n" +"a copy of this software and associated documentation files (the\n" +"\"Software\"), to deal in the Software without restriction, including\n" +"without limitation the rights to use, copy, modify, merge, publish,\n" +"distribute, sublicense, and/or sell copies of the Software, and to\n" +"permit persons to whom the Software is furnished to do so, subject to\n" +"the following conditions:" +msgstr "" + +#: shell-novice/LICENSE.md:63 +msgid "" +"The above copyright notice and this permission notice shall be\n" +"included in all copies or substantial portions of the Software." +msgstr "" + +#: shell-novice/LICENSE.md:66 +msgid "" +"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n" +"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n" +"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n" +"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n" +"LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n" +"OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n" +"WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." +msgstr "" + +# header +#: shell-novice/LICENSE.md:74 +msgid "## Trademark" +msgstr "" + +#: shell-novice/LICENSE.md:76 +msgid "" +"\"Software Carpentry\" and \"Data Carpentry\" and their respective logos\n" +"are registered trademarks of [Community Initiatives][CI]." +msgstr "" + +#: shell-novice/LICENSE.md:79 +msgid "" +"[cc-by-human]: https://creativecommons.org/licenses/by/4.0/\n" +"[cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode\n" +"[mit-license]: http://opensource.org/licenses/mit-license.html\n" +"[ci]: http://communityin.org/\n" +"[osi]: http://opensource.org" +msgstr "" + +#: shell-novice/README.md:1 +msgid "" +"shell-novice\n" +"============" +msgstr "" + +#: shell-novice/README.md:4 +msgid "" +"An introduction to the Unix shell for people who have never used the command " +"line before.\n" +"Please see for a rendered " +"version of this material,\n" +"[the lesson template documentation][lesson-example]\n" +"for instructions on formatting, building, and submitting material,\n" +"or run `make` in this directory for a list of helpful commands." +msgstr "" + +#: shell-novice/README.md:10 +msgid "Maintainers:" +msgstr "" + +# unordered list +#: shell-novice/README.md:12 +msgid "* [Gabriel Devenyi][devenyi_gabriel]" +msgstr "" + +# unordered list +#: shell-novice/README.md:13 +msgid "* [Ashwin Srinath][srinath_ashwin]" +msgstr "" + +# unordered list +#: shell-novice/README.md:14 +msgid "* [Colin Morris][colin_morris]" +msgstr "" + +# unordered list +#: shell-novice/README.md:15 +msgid "* [Will Pitchers][will_pitchers]" +msgstr "" + +#: shell-novice/README.md:17 +msgid "" +"[devenyi_gabriel]: http://software-carpentry.org/team/#devenyi_gabriel\n" +"[srinath_ashwin]: http://software-carpentry.org/team/#srinath_ashwin\n" +"[colin_morris]: https://github.com/colinmorris\n" +"[will_pitchers]: https://software-carpentry.org/team/#pitchers_w\n" +"[lesson-example]: https://swcarpentry.github.io/lesson-example/" +msgstr "" + +# Front Matter +#: shell-novice/_episodes/01-intro.md:1 +msgid "" +"---\n" +"title: \"Introducing the Shell\"\n" +"teaching: 5\n" +"exercises: 0\n" +"questions:\n" +"- \"What is a command shell and why would I use one?\"\n" +"objectives:\n" +"- \"Explain how the shell relates to the keyboard, the screen, the operating " +"system, and users' programs.\"\n" +"- \"Explain when and why command-line interfaces should be used instead of " +"graphical interfaces.\"\n" +"keypoints:\n" +"- \"Explain the steps in the shell's read-run-print cycle.\"\n" +"- \"Most commands take flags (options) which begin with a `-`.\"\n" +"- \"Identify the actual command, flags, and filenames in a command-line call." +"\"\n" +"- \"Explain the steps in the shell's read-run-print cycle.\"\n" +"- \"Demonstrate the use of tab completion and explain its advantages.\"\n" +"keypoints:\n" +"- \"A shell is a program whose primary purpose is to read commands and run " +"other programs.\"\n" +"- \"The shell's main advantages are its high action-to-keystroke ratio, its " +"support for automating repetitive tasks, and its capacity to access " +"networked machines.\"\n" +"- \"The shell's main disadvantages are its primarily textual nature and how " +"cryptic its commands and operation can be.\"\n" +"---" +msgstr "" + +# header +#: shell-novice/_episodes/01-intro.md:21 +msgid "### Background" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:22 +msgid "At a high level, computers do four things:" +msgstr "" + +# unordered list +#: shell-novice/_episodes/01-intro.md:24 +msgid "- run programs" +msgstr "" + +# unordered list +#: shell-novice/_episodes/01-intro.md:25 +msgid "- store data" +msgstr "" + +# unordered list +#: shell-novice/_episodes/01-intro.md:26 +msgid "- communicate with each other, and" +msgstr "" + +# unordered list +#: shell-novice/_episodes/01-intro.md:27 +msgid "- interact with us" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:29 +msgid "" +"They can do the last of these in many different ways,\n" +"including through a keyboard and mouse, or touch screen interfaces, or " +"speech recognition using systems.\n" +"While such hardware interfaces are becoming more commonplace, most " +"interaction is still\n" +"done using screens, mice, touchpads and keyboards." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:34 +msgid "" +"We are all familiar with **graphical user interfaces** (GUI - windows, icons " +"and pointers). \n" +"They are easy to learn and fantastic for simple tasks where a vocabulary " +"consisting of\n" +"\"click\" translates easily into \"do the thing I want\". But this magic " +"relies on \n" +"wanting a simple set of things, and having programs that can do exactly " +"those things." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:39 +msgid "" +"If you wish to do complex, purpose-specific things it helps to have a richer " +"means\n" +"of expressing your instructions to the computer. It doesn't need to be " +"complicated or\n" +"difficult, just a vocabulary of commands and a simple grammar for using them." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:43 +msgid "" +"This is what the shell provides - a simple language and a **command-line " +"interface** \n" +"to use it through. " +msgstr "" + +#: shell-novice/_episodes/01-intro.md:46 +msgid "" +"The heart of a command-line interface is a **read-evaluate-print loop**, or " +"REPL, called\n" +"so because when you type a command and press the Enter (or Return) key, the " +"shell:\n" +"1. Reads it\n" +"2. Executes (or \"evaluates\" it)\n" +"3. Prints the output" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:52 +msgid "and then prints the prompt and waits for you to enter another command." +msgstr "" + +# header +#: shell-novice/_episodes/01-intro.md:54 +msgid "### The Shell" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:56 +msgid "" +"A shell is a program like any other.\n" +"What's special about it is that its job is to run other programs\n" +"rather than to do calculations itself.\n" +"The most popular Unix shell is Bash,\n" +"the Bourne Again SHell\n" +"(so-called because it's derived from a shell written by Stephen Bourne).\n" +"Bash is the default shell on most modern implementations of Unix\n" +"and in most packages that provide Unix-like tools for Windows." +msgstr "" + +# header +#: shell-novice/_episodes/01-intro.md:65 +msgid "### What does it look like?" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:67 +msgid "A typical shell command and output looks something like this:" +msgstr "" + +# code block +#: shell-novice/_episodes/01-intro.md:69 +msgid "" +"~~~\n" +"bash-3.2$ \n" +"bash-3.2$ ls -F / \n" +"Applications/ System/\n" +"Library/ Users/\n" +"Network/ Volumes/\n" +"bash-3.2$ \n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:77 +#: shell-novice/_episodes/02-filedir.md:50 +#: shell-novice/_episodes/02-filedir.md:129 +#: shell-novice/_episodes/02-filedir.md:152 +#: shell-novice/_episodes/02-filedir.md:201 +#: shell-novice/_episodes/02-filedir.md:409 +#: shell-novice/_episodes/02-filedir.md:437 +#: shell-novice/_episodes/02-filedir.md:464 +#: shell-novice/_episodes/02-filedir.md:477 +#: shell-novice/_episodes/02-filedir.md:487 +#: shell-novice/_episodes/02-filedir.md:501 +#: shell-novice/_episodes/02-filedir.md:521 +#: shell-novice/_episodes/02-filedir.md:533 +#: shell-novice/_episodes/02-filedir.md:546 +#: shell-novice/_episodes/02-filedir.md:599 +#: shell-novice/_episodes/02-filedir.md:606 +#: shell-novice/_episodes/02-filedir.md:623 +#: shell-novice/_episodes/02-filedir.md:650 +#: shell-novice/_episodes/02-filedir.md:660 +#: shell-novice/_episodes/02-filedir.md:799 +#: shell-novice/_episodes/02-filedir.md:808 +#: shell-novice/_episodes/02-filedir.md:816 +#: shell-novice/_episodes/03-create.md:30 +#: shell-novice/_episodes/03-create.md:40 +#: shell-novice/_episodes/03-create.md:53 +#: shell-novice/_episodes/03-create.md:64 +#: shell-novice/_episodes/03-create.md:112 +#: shell-novice/_episodes/03-create.md:121 +#: shell-novice/_episodes/03-create.md:183 +#: shell-novice/_episodes/03-create.md:236 +#: shell-novice/_episodes/03-create.md:246 +#: shell-novice/_episodes/03-create.md:265 +#: shell-novice/_episodes/03-create.md:276 +#: shell-novice/_episodes/03-create.md:286 +#: shell-novice/_episodes/03-create.md:294 +#: shell-novice/_episodes/03-create.md:309 +#: shell-novice/_episodes/03-create.md:353 +#: shell-novice/_episodes/03-create.md:365 +#: shell-novice/_episodes/03-create.md:379 +#: shell-novice/_episodes/03-create.md:392 +#: shell-novice/_episodes/03-create.md:419 +#: shell-novice/_episodes/03-create.md:427 +#: shell-novice/_episodes/03-create.md:436 +#: shell-novice/_episodes/03-create.md:484 +#: shell-novice/_episodes/03-create.md:499 +#: shell-novice/_episodes/04-pipefilter.md:37 +#: shell-novice/_episodes/04-pipefilter.md:55 +#: shell-novice/_episodes/04-pipefilter.md:177 +#: shell-novice/_episodes/04-pipefilter.md:201 +#: shell-novice/_episodes/04-pipefilter.md:215 +#: shell-novice/_episodes/04-pipefilter.md:275 +#: shell-novice/_episodes/04-pipefilter.md:351 +#: shell-novice/_episodes/04-pipefilter.md:374 +#: shell-novice/_episodes/04-pipefilter.md:413 +#: shell-novice/_episodes/04-pipefilter.md:437 +#: shell-novice/_episodes/04-pipefilter.md:455 +#: shell-novice/_episodes/04-pipefilter.md:746 +#: shell-novice/_episodes/04-pipefilter.md:766 +#: shell-novice/_episodes/04-pipefilter.md:788 +#: shell-novice/_episodes/04-pipefilter.md:808 +#: shell-novice/_episodes/05-loop.md:39 shell-novice/_episodes/05-loop.md:46 +#: shell-novice/_episodes/05-loop.md:70 shell-novice/_episodes/05-loop.md:223 +#: shell-novice/_episodes/05-loop.md:233 shell-novice/_episodes/05-loop.md:295 +#: shell-novice/_episodes/05-loop.md:306 shell-novice/_episodes/05-loop.md:327 +#: shell-novice/_episodes/05-loop.md:392 shell-novice/_episodes/05-loop.md:402 +#: shell-novice/_episodes/05-loop.md:409 shell-novice/_episodes/05-loop.md:439 +#: shell-novice/_episodes/05-loop.md:462 shell-novice/_episodes/05-loop.md:489 +#: shell-novice/_episodes/05-loop.md:497 shell-novice/_episodes/05-loop.md:511 +#: shell-novice/_episodes/06-script.md:36 +#: shell-novice/_episodes/06-script.md:64 +#: shell-novice/_episodes/06-script.md:99 +#: shell-novice/_episodes/06-script.md:115 +#: shell-novice/_episodes/06-script.md:131 +#: shell-novice/_episodes/06-script.md:157 +#: shell-novice/_episodes/06-script.md:169 +#: shell-novice/_episodes/06-script.md:186 +#: shell-novice/_episodes/06-script.md:204 +#: shell-novice/_episodes/06-script.md:226 +#: shell-novice/_episodes/06-script.md:248 +#: shell-novice/_episodes/06-script.md:260 +#: shell-novice/_episodes/06-script.md:351 +#: shell-novice/_episodes/06-script.md:411 +#: shell-novice/_episodes/06-script.md:419 +#: shell-novice/_episodes/06-script.md:426 +#: shell-novice/_episodes/06-script.md:443 shell-novice/_episodes/07-find.md:39 +#: shell-novice/_episodes/07-find.md:69 shell-novice/_episodes/07-find.md:87 +#: shell-novice/_episodes/07-find.md:107 shell-novice/_episodes/07-find.md:123 +#: shell-novice/_episodes/07-find.md:141 shell-novice/_episodes/07-find.md:159 +#: shell-novice/_episodes/07-find.md:172 shell-novice/_episodes/07-find.md:187 +#: shell-novice/_episodes/07-find.md:207 shell-novice/_episodes/07-find.md:405 +#: shell-novice/_episodes/07-find.md:442 shell-novice/_episodes/07-find.md:460 +#: shell-novice/_episodes/07-find.md:479 shell-novice/_episodes/07-find.md:495 +#: shell-novice/_episodes/07-find.md:508 shell-novice/_episodes/07-find.md:539 +#: shell-novice/_episodes/07-find.md:559 shell-novice/_episodes/07-find.md:574 +msgid "{: .language-bash}" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:79 +msgid "" +"The first line shows only a **prompt**, indicating that the shell is " +"waiting\n" +"for input. Your shell may use different text for the prompt. Most " +"importantly: \n" +"when typing commands, either from these lessons or from other sources,\n" +"*do not type the prompt*, only the commands that follow it." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:84 +msgid "" +"The part that you type (in this example `ls -F /`)\n" +"typically has the following structure: a **command**,\n" +"some **flags** (also called **options** or **switches**) and an " +"**argument**.\n" +"Flags start with a dash (`-`), and change the behaviour of a command.\n" +"Arguments tell the command what to operate on (e.g. files and directories).\n" +"Sometimes flags and arguments are referred to as parameters.\n" +"A command can be called with more than one flag and more than one argument: " +"but a\n" +"command doesn't always require an argument or a flag." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:93 +msgid "" +"In the example above, our **command** is `ls`, with a **flag** `-F` and an\n" +"**argument** `/`. Each part is separated by spaces: if you omit the space \n" +"between `ls` and `-F` the shell will look for a command called `ls-F`, " +"which \n" +"doesn't exist. Also, capitalization matters: `LS` is different to `ls`. " +msgstr "" + +#: shell-novice/_episodes/01-intro.md:98 +msgid "" +"Next we see the output that our command produced. In this case it is a " +"listing \n" +"of files and folders in a location called `/` - we'll cover what all these " +"mean \n" +"later today. Those with a Mac might recognize the output in this example." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:102 +msgid "" +"Finally, the shell again prints the prompt and waits for you to type the " +"next \n" +"command." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:105 +msgid "" +"In the examples for this lesson, we'll show the prompt as `$ `. You can make " +"your \n" +"prompt look the same by entering the command `PS1='$ '`. But you can also " +"leave \n" +"your prompt as it is - often the prompt includes useful information about " +"who and where \n" +"you are." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:110 +msgid "" +"Open a shell window and try entering `ls -F /` for yourself (don't forget " +"that spaces\n" +"and capitalization are important!). You can change the prompt too, if you " +"like." +msgstr "" + +# header +#: shell-novice/_episodes/01-intro.md:113 +msgid "### How does the shell know what `ls` and its flags mean?" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:115 +msgid "" +"Every command is a program stored somewhere on the computer, and the shell " +"keeps a\n" +"list of places to search for commands (the list is in a **variable** called `" +"$PATH`, \n" +"but those are concepts we'll meet later and not too important at the " +"moment). Recall\n" +"that commands, flags and arguments are separated by spaces." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:120 +msgid "" +"So let's look at the REPL (read-evaluate-print loop) in more detail. Notice " +"that the\n" +"\"evaluate\" step is made of two parts:" +msgstr "" + +# ordered list +#: shell-novice/_episodes/01-intro.md:123 +msgid "1. Read what was typed (`ls -F /` in our example) " +msgstr "" + +#: shell-novice/_episodes/01-intro.md:124 +msgid "" +" The shell uses the spaces to split the line into the command, flags, and " +"arguments\n" +"2. Evaluate: \n" +" a. Find a program called `ls` \n" +" b. Execute it, passing it the flags and arguments (`-F` and `/`) to \n" +" interpret as the program sees fit \n" +"3. Print the output produced by the program" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:131 +msgid "and then print the prompt and wait for you to enter another command." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:133 +msgid "> ## Command not found " +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:134 +msgid "" +"> If the shell can't find a program whose name is the command you typed, it " +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:135 +msgid "> will print an erorr message like:" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:136 +#: shell-novice/_episodes/01-intro.md:142 shell-novice/_episodes/05-loop.md:349 +#: shell-novice/_episodes/05-loop.md:351 shell-novice/_episodes/07-find.md:283 +#: shell-novice/_episodes/07-find.md:286 shell-novice/_episodes/07-find.md:661 +msgid "> " +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:137 +#: shell-novice/_episodes/01-intro.md:140 +#: shell-novice/_episodes/03-create.md:570 +#: shell-novice/_episodes/03-create.md:572 +#: shell-novice/_episodes/03-create.md:574 +#: shell-novice/_episodes/03-create.md:576 +#: shell-novice/_episodes/03-create.md:578 +#: shell-novice/_episodes/03-create.md:583 +#: shell-novice/_episodes/03-create.md:633 +#: shell-novice/_episodes/03-create.md:635 +#: shell-novice/_episodes/03-create.md:637 +#: shell-novice/_episodes/03-create.md:639 +#: shell-novice/_episodes/03-create.md:675 +#: shell-novice/_episodes/03-create.md:677 +#: shell-novice/_episodes/05-loop.md:352 shell-novice/_episodes/05-loop.md:357 +#: shell-novice/_episodes/07-find.md:287 shell-novice/_episodes/07-find.md:293 +msgid "> ~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:138 +msgid "> $ ls-F" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:139 +msgid "> -bash: ls-F: command not found" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:141 +#: shell-novice/_episodes/03-create.md:573 +#: shell-novice/_episodes/03-create.md:584 +#: shell-novice/_episodes/03-create.md:636 +#: shell-novice/_episodes/03-create.md:678 +#: shell-novice/_episodes/05-loop.md:358 +msgid "> {: .language-bash}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:143 +msgid "" +"> Usually this means that you have mis-typed the command - in this case we " +"omitted" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/01-intro.md:144 +msgid "> the space between `ls` and `-F`. " +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/01-intro.md:145 +#: shell-novice/_episodes/02-filedir.md:70 +#: shell-novice/_episodes/02-filedir.md:107 +#: shell-novice/_episodes/02-filedir.md:190 +#: shell-novice/_episodes/02-filedir.md:337 +#: shell-novice/_episodes/02-filedir.md:576 +#: shell-novice/_episodes/02-filedir.md:589 +#: shell-novice/_episodes/02-filedir.md:678 +#: shell-novice/_episodes/02-filedir.md:781 +#: shell-novice/_episodes/03-create.md:77 +#: shell-novice/_episodes/03-create.md:105 +#: shell-novice/_episodes/03-create.md:145 +#: shell-novice/_episodes/03-create.md:175 +#: shell-novice/_episodes/03-create.md:257 +#: shell-novice/_episodes/03-create.md:344 +#: shell-novice/_episodes/03-create.md:532 +#: shell-novice/_episodes/04-pipefilter.md:99 +#: shell-novice/_episodes/04-pipefilter.md:297 +#: shell-novice/_episodes/04-pipefilter.md:402 +#: shell-novice/_episodes/04-pipefilter.md:558 +#: shell-novice/_episodes/05-loop.md:85 shell-novice/_episodes/05-loop.md:195 +#: shell-novice/_episodes/05-loop.md:209 shell-novice/_episodes/05-loop.md:381 +#: shell-novice/_episodes/05-loop.md:517 shell-novice/_episodes/05-loop.md:563 +#: shell-novice/_episodes/05-loop.md:579 shell-novice/_episodes/06-script.md:89 +#: shell-novice/_episodes/06-script.md:147 +#: shell-novice/_episodes/06-script.md:337 shell-novice/_episodes/07-find.md:62 +#: shell-novice/_episodes/07-find.md:280 shell-novice/_episodes/07-find.md:524 +#: shell-novice/_episodes/07-find.md:631 shell-novice/setup.md:63 +msgid "{: .callout}" +msgstr "" + +# header +#: shell-novice/_episodes/01-intro.md:147 +msgid "### Is it difficult?" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:149 +msgid "" +"It isn't difficult, but it is a different model of interacting than a GUI, " +"and that \n" +"will take some effort - and some time - to learn. A GUI \n" +"presents you with choices and you select one. With a CLI the choices are " +"combinations \n" +"of commands and parameters, more like words in a language than buttons on a " +"screen. They\n" +"are not presented to you so\n" +"you must learn a few, like learning some vocabulary in a new language. But a " +"small \n" +"number of commands gets you a long way, and we'll cover those essential few " +"today." +msgstr "" + +# header +#: shell-novice/_episodes/01-intro.md:157 +msgid "### Flexibility and automation " +msgstr "" + +#: shell-novice/_episodes/01-intro.md:159 +msgid "" +"The grammar of a shell allows you to combine existing tools into powerful\n" +"pipelines and handle large volumes of data automatically. Sequences of\n" +"commands can be written into a *script*, improving the reproducibility of \n" +"workflows and allowing you to repeat them easily." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:164 +msgid "" +"In addition, the command line is often the easiest way to interact with " +"remote machines and supercomputers.\n" +"Familiarity with the shell is near essential to run a variety of specialized " +"tools and resources\n" +"including high-performance computing systems.\n" +"As clusters and cloud computing systems become more popular for scientific " +"data crunching,\n" +"being able to interact with the shell is becoming a necessary skill.\n" +"We can build on the command-line skills covered here\n" +"to tackle a wide range of scientific questions and computational challenges." +msgstr "" + +# header +#: shell-novice/_episodes/01-intro.md:172 +msgid "## Nelle's Pipeline: Starting Point" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:174 +msgid "" +"Nelle Nemo, a marine biologist,\n" +"has just returned from a six-month survey of the\n" +"[North Pacific Gyre](http://en.wikipedia.org/wiki/North_Pacific_Gyre),\n" +"where she has been sampling gelatinous marine life in the\n" +"[Great Pacific Garbage Patch](http://en.wikipedia.org/wiki/" +"Great_Pacific_Garbage_Patch).\n" +"She has 1520 samples in all and now needs to:" +msgstr "" + +# ordered list +#: shell-novice/_episodes/01-intro.md:181 +msgid "1. Run each sample through an assay machine" +msgstr "" + +#: shell-novice/_episodes/01-intro.md:182 +msgid "" +" that will measure the relative abundance of 300 different proteins.\n" +" The machine's output for a single sample is\n" +" a file with one line for each protein.\n" +"2. Calculate statistics for each of the proteins separately\n" +" using a program her supervisor wrote called `goostats`.\n" +"3. Write up results.\n" +" Her supervisor would really like her to do this by the end of the month\n" +" so that her paper can appear in an upcoming special issue of *Aquatic " +"Goo Letters*." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:191 +msgid "" +"It takes about half an hour for the assay machine to process each sample.\n" +"The good news is that\n" +"it only takes two minutes to set each one up.\n" +"Since her lab has eight assay machines that she can use in parallel,\n" +"this step will \"only\" take about two weeks." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:197 +msgid "" +"The bad news is that if she has to run `goostats` by hand,\n" +"she'll have to enter filenames and click \"OK\" 1520 times.\n" +"At 30 seconds per sample,\n" +"the whole process will take more than 12 hours\n" +"(and that's assuming the best-case scenario where she is ready to enter the " +"next file name\n" +"as soon as the previous sample analysis has finished).\n" +"This zero-breaks always-ready scenario is only achieveable by a machine so " +"it would\n" +"likely take much longer than 12 hours, not to mention that\n" +"the chances of her typing all of those commands correctly are practically " +"zero.\n" +"Missing that paper deadline is looking increasingly likely." +msgstr "" + +#: shell-novice/_episodes/01-intro.md:208 +msgid "" +"The next few lessons will explore what she should do instead.\n" +"More specifically,\n" +"they explain how she can use a command shell\n" +"to automate the repetitive steps in her processing pipeline\n" +"so that her computer can work 24 hours a day while she writes her paper.\n" +"As a bonus,\n" +"once she has put a processing pipeline together,\n" +"she will be able to use it again whenever she collects more data." +msgstr "" + +# Front Matter +#: shell-novice/_episodes/02-filedir.md:1 +msgid "" +"---\n" +"title: \"Navigating Files and Directories\"\n" +"teaching: 30\n" +"exercises: 10\n" +"questions:\n" +"- \"How can I move around on my computer?\"\n" +"- \"How can I see what files and directories I have?\"\n" +"- \"How can I specify the location of a file or directory on my computer?\"\n" +"objectives:\n" +"- \"Explain the similarities and differences between a file and a directory." +"\"\n" +"- \"Translate an absolute path into a relative path and vice versa.\"\n" +"- \"Construct absolute and relative paths that identify specific files and " +"directories.\"\n" +"- \"Demonstrate the use of tab completion, and explain its advantages.\"\n" +"keypoints:\n" +"- \"The file system is responsible for managing information on the disk.\"\n" +"- \"Information is stored in files, which are stored in directories " +"(folders).\"\n" +"- \"Directories can also store other directories, which forms a directory " +"tree.\"\n" +"- \"`cd path` changes the current working directory.\"\n" +"- \"`ls path` prints a listing of a specific file or directory; `ls` on its " +"own lists the current working directory.\"\n" +"- \"`pwd` prints the user's current working directory.\"\n" +"- \"`whoami` shows the user's current identity.\"\n" +"- \"`/` on its own is the root directory of the whole file system.\"\n" +"- \"A relative path specifies a location starting from the current location." +"\"\n" +"- \"An absolute path specifies a location from the root of the file system." +"\"\n" +"- \"Directory names in a path are separated with `/` on Unix, but `\\\\\\\\` " +"on Windows.\"\n" +"- \"`..` means 'the directory above the current one'; `.` on its own means " +"'the current directory'.\"\n" +"- \"Most files' names are `something.extension`. The extension isn't " +"required, and doesn't guarantee anything, but is normally used to indicate " +"the type of data in the file.\"\n" +"---" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:30 +msgid "" +"The part of the operating system responsible for managing files and " +"directories \n" +"is called the **file system**.\n" +"It organizes our data into files,\n" +"which hold information,\n" +"and directories (also called \"folders\"),\n" +"which hold files or other directories." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:37 +msgid "" +"Several commands are frequently used to create, inspect, rename, and delete " +"files and directories.\n" +"To start exploring them, we'll go to our open shell window:" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:40 +msgid "" +"First let's find out where we are by running a command called `pwd`\n" +"(which stands for \"print working directory\"). Directories are like " +"*places* - at any time\n" +"while we are using the shell we are in exactly one place, called\n" +"our **current working directory**. Commands mostly read and write files in " +"the \n" +"current working directory, i.e. \"here\", so knowing where you are before " +"running\n" +"a command is important. `pwd` shows you where you are:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:47 +#: shell-novice/_episodes/02-filedir.md:474 +#: shell-novice/_episodes/02-filedir.md:530 +#: shell-novice/_episodes/02-filedir.md:603 +#: shell-novice/_episodes/02-filedir.md:647 +#: shell-novice/_episodes/03-create.md:27 +#: shell-novice/_episodes/03-create.md:262 +#: shell-novice/_episodes/03-create.md:350 +msgid "" +"~~~\n" +"$ pwd\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:52 +#: shell-novice/_episodes/02-filedir.md:608 +msgid "" +"~~~\n" +"/Users/nelle\n" +"~~~" +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/02-filedir.md:55 +#: shell-novice/_episodes/02-filedir.md:135 +#: shell-novice/_episodes/02-filedir.md:158 +#: shell-novice/_episodes/02-filedir.md:321 +#: shell-novice/_episodes/02-filedir.md:414 +#: shell-novice/_episodes/02-filedir.md:443 +#: shell-novice/_episodes/02-filedir.md:482 +#: shell-novice/_episodes/02-filedir.md:493 +#: shell-novice/_episodes/02-filedir.md:538 +#: shell-novice/_episodes/02-filedir.md:552 +#: shell-novice/_episodes/02-filedir.md:611 +#: shell-novice/_episodes/02-filedir.md:655 +#: shell-novice/_episodes/03-create.md:35 +#: shell-novice/_episodes/03-create.md:45 +#: shell-novice/_episodes/03-create.md:69 +#: shell-novice/_episodes/03-create.md:188 +#: shell-novice/_episodes/03-create.md:270 +#: shell-novice/_episodes/03-create.md:281 +#: shell-novice/_episodes/03-create.md:358 +#: shell-novice/_episodes/03-create.md:370 +#: shell-novice/_episodes/03-create.md:397 +#: shell-novice/_episodes/03-create.md:441 +#: shell-novice/_episodes/03-create.md:489 +#: shell-novice/_episodes/04-pipefilter.md:43 +#: shell-novice/_episodes/04-pipefilter.md:66 +#: shell-novice/_episodes/04-pipefilter.md:188 +#: shell-novice/_episodes/04-pipefilter.md:220 +#: shell-novice/_episodes/04-pipefilter.md:286 +#: shell-novice/_episodes/04-pipefilter.md:362 +#: shell-novice/_episodes/04-pipefilter.md:379 +#: shell-novice/_episodes/04-pipefilter.md:418 +#: shell-novice/_episodes/04-pipefilter.md:448 +#: shell-novice/_episodes/04-pipefilter.md:460 +#: shell-novice/_episodes/04-pipefilter.md:759 +#: shell-novice/_episodes/04-pipefilter.md:775 +#: shell-novice/_episodes/04-pipefilter.md:797 +#: shell-novice/_episodes/04-pipefilter.md:813 +#: shell-novice/_episodes/05-loop.md:80 shell-novice/_episodes/05-loop.md:313 +#: shell-novice/_episodes/05-loop.md:449 shell-novice/_episodes/05-loop.md:472 +#: shell-novice/_episodes/05-loop.md:528 shell-novice/_episodes/06-script.md:73 +#: shell-novice/_episodes/06-script.md:106 +#: shell-novice/_episodes/06-script.md:124 +#: shell-novice/_episodes/06-script.md:140 +#: shell-novice/_episodes/06-script.md:162 +#: shell-novice/_episodes/06-script.md:178 +#: shell-novice/_episodes/06-script.md:195 +#: shell-novice/_episodes/06-script.md:211 +#: shell-novice/_episodes/06-script.md:255 +#: shell-novice/_episodes/06-script.md:272 shell-novice/_episodes/07-find.md:54 +#: shell-novice/_episodes/07-find.md:76 shell-novice/_episodes/07-find.md:93 +#: shell-novice/_episodes/07-find.md:112 shell-novice/_episodes/07-find.md:128 +#: shell-novice/_episodes/07-find.md:148 shell-novice/_episodes/07-find.md:165 +#: shell-novice/_episodes/07-find.md:179 shell-novice/_episodes/07-find.md:200 +#: shell-novice/_episodes/07-find.md:230 shell-novice/_episodes/07-find.md:422 +#: shell-novice/_episodes/07-find.md:451 shell-novice/_episodes/07-find.md:472 +#: shell-novice/_episodes/07-find.md:484 shell-novice/_episodes/07-find.md:516 +#: shell-novice/_episodes/07-find.md:548 shell-novice/_episodes/07-find.md:579 +msgid "{: .output}" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:57 +msgid "" +"Here,\n" +"the computer's response is `/Users/nelle`,\n" +"which is Nelle's **home directory**:" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:61 +msgid "> ## Home Directory Variation" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:62 +msgid "" +">\n" +"> The home directory path will look different on different operating " +"systems.\n" +"> On Linux it may look like `/home/nelle`,\n" +"> and on Windows it will be similar to `C:\\Documents and Settings\\nelle` " +"or\n" +"> `C:\\Users\\nelle`. \n" +"> (Note that it may look slightly different for different versions of " +"Windows.)\n" +"> In future examples, we've used Mac output as the default - Linux and " +"Windows\n" +"> output may differ slightly, but should be generally similar. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:72 +msgid "" +"To understand what a \"home directory\" is,\n" +"let's have a look at how the file system as a whole is organized. For the\n" +"sake of this example, we'll be\n" +"illustrating the filesystem on our scientist Nelle's computer. After this\n" +"illustration, you'll be learning commands to explore your own filesystem,\n" +"which will be constructed in a similar way, but not be exactly identical. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:79 +msgid "On Nelle's computer, the filesystem looks like this:" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:81 +msgid "![The File System](../fig/filesystem.svg)" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:83 +msgid "" +"At the top is the **root directory**\n" +"that holds everything else.\n" +"We refer to it using a slash character `/` on its own;\n" +"this is the leading slash in `/Users/nelle`." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:88 +msgid "" +"Inside that directory are several other directories:\n" +"`bin` (which is where some built-in programs are stored),\n" +"`data` (for miscellaneous data files),\n" +"`Users` (where users' personal directories are located),\n" +"`tmp` (for temporary files that don't need to be stored long-term),\n" +"and so on. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:95 +msgid "" +"We know that our current working directory `/Users/nelle` is stored inside `/" +"Users`\n" +"because `/Users` is the first part of its name.\n" +"Similarly,\n" +"we know that `/Users` is stored inside the root directory `/`\n" +"because its name begins with `/`." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:101 +msgid "> ## Slashes" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:102 +msgid "" +">\n" +"> Notice that there are two meanings for the `/` character.\n" +"> When it appears at the front of a file or directory name,\n" +"> it refers to the root directory. When it appears *inside* a name,\n" +"> it's just a separator." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:109 +msgid "" +"Underneath `/Users`,\n" +"we find one directory for each user with an account on Nelle's machine,\n" +"her colleagues the Mummy and Wolfman. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:113 +msgid "![Home Directories](../fig/home-directories.svg)" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:115 +msgid "" +"The Mummy's files are stored in `/Users/imhotep`,\n" +"Wolfman's in `/Users/larry`,\n" +"and Nelle's in `/Users/nelle`. Because Nelle is the user in our\n" +"examples here, this is why we get `/Users/nelle` as our home directory. \n" +"Typically, when you open a new command prompt you will be in\n" +"your home directory to start. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:122 +msgid "" +"Now let's learn the command that will let us see the contents of our\n" +"own filesystem. We can see what's in our home directory by running `ls`,\n" +"which stands for \"listing\":" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:126 +#: shell-novice/_episodes/03-create.md:180 +#: shell-novice/_episodes/03-create.md:243 +msgid "" +"~~~\n" +"$ ls\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:131 +msgid "" +"~~~\n" +"Applications Documents Library Music Public\n" +"Desktop Downloads Movies Pictures\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:137 +msgid "" +"(Again, your results may be slightly different depending on your operating\n" +"system and how you have customized your filesystem.)" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:140 +msgid "" +"`ls` prints the names of the files and directories in the current " +"directory. \n" +"We can make its output more comprehensible by using the **flag** `-F`\n" +"(also known as a **switch** or an **option**) ,\n" +"which tells `ls` to add a marker to file and directory names to indicate " +"what\n" +"they are. A trailing `/` indicates that this is a directory. Depending on " +"your\n" +"settings, it might also use colors to indicate whether each entry is a file " +"or \n" +"directory.\n" +"You might recall that we used `ls -F` in an earlier example." +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:149 +#: shell-novice/_episodes/02-filedir.md:484 +#: shell-novice/_episodes/03-create.md:37 +#: shell-novice/_episodes/03-create.md:61 +msgid "" +"~~~\n" +"$ ls -F\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:154 +msgid "" +"~~~\n" +"Applications/ Documents/ Library/ Music/ Public/\n" +"Desktop/ Downloads/ Movies/ Pictures/\n" +"~~~" +msgstr "" + +# header +#: shell-novice/_episodes/02-filedir.md:160 +msgid "### Getting help" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:162 +msgid "" +"`ls` has lots of other **flags**. There are two common ways to find out " +"how \n" +"to use a command and what flags it accepts:" +msgstr "" + +# ordered list +#: shell-novice/_episodes/02-filedir.md:165 +msgid "1. We can pass a `--help` flag to the command, such as:" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:166 +msgid "" +" ~~~\n" +" $ ls --help\n" +" ~~~" +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/02-filedir.md:169 +#: shell-novice/_episodes/02-filedir.md:175 shell-novice/_extras/guide.md:210 +msgid " {: .bash}" +msgstr "" + +# ordered list +#: shell-novice/_episodes/02-filedir.md:171 +msgid "2. We can read its manual with `man`, such as:" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:172 +msgid "" +" ~~~\n" +" $ man ls \n" +" ~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:177 +msgid "" +"If you use a Mac, or Git for Windows, you might find that only one of these " +"works \n" +"(probably `man` on Mac and `--help` in Windows). We'll describe both ways." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:180 +msgid "" +"Of course there is a third way: searching the internet via your web " +"browser. \n" +"When using internet search, including the phrase `unix man page` in your " +"search\n" +"query will help to find relevant results." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:184 +msgid "> ## Manual pages on the web" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:185 +msgid "" +">\n" +"> GNU provides links to its\n" +"> [manuals](http://www.gnu.org/manual/manual.html) including the\n" +"> [core GNU utilities](http://www.gnu.org/software/coreutils/manual/" +"coreutils.html),\n" +"> which covers many commands introduced within this lesson." +msgstr "" + +# header +#: shell-novice/_episodes/02-filedir.md:192 +msgid "#### The `--help` flag" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:194 +msgid "" +"Many bash commands, and programs that people have written that can be\n" +"run from within bash, support a `--help` flag to display more\n" +"information on how to use the command or program." +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:198 +msgid "" +"~~~\n" +"$ ls --help\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:203 +msgid "" +"~~~\n" +"Usage: ls [OPTION]... [FILE]...\n" +"List information about the FILEs (the current directory by default).\n" +"Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n" +"\n" +"Mandatory arguments to long options are mandatory for short options too.\n" +" -a, --all do not ignore entries starting with .\n" +" -A, --almost-all do not list implied . and ..\n" +" --author with -l, print the author of each file\n" +" -b, --escape print C-style escapes for nongraphic " +"characters\n" +" --block-size=SIZE scale sizes by SIZE before printing them; e." +"g.,\n" +" '--block-size=M' prints sizes in units of\n" +" 1,048,576 bytes; see SIZE format below\n" +" -B, --ignore-backups do not list implied entries ending with ~\n" +" -c with -lt: sort by, and show, ctime (time of " +"last\n" +" modification of file status information);\n" +" with -l: show ctime and sort by name;\n" +" otherwise: sort by ctime, newest first\n" +" -C list entries by columns\n" +" --color[=WHEN] colorize the output; WHEN can be " +"'always' (default\n" +" if omitted), 'auto', or 'never'; more info " +"below\n" +" -d, --directory list directories themselves, not their " +"contents\n" +" -D, --dired generate output designed for Emacs' dired mode\n" +" -f do not sort, enable -aU, disable -ls --color\n" +" -F, --classify append indicator (one of */=>@|) to entries\n" +" --file-type likewise, except do not append '*'\n" +" --format=WORD across -x, commas -m, horizontal -x, long -l,\n" +" single-column -1, verbose -l, vertical -C\n" +" --full-time like -l --time-style=full-iso\n" +" -g like -l, but do not list owner\n" +" --group-directories-first\n" +" group directories before files;\n" +" can be augmented with a --sort option, but " +"any\n" +" use of --sort=none (-U) disables grouping\n" +" -G, --no-group in a long listing, don't print group names\n" +" -h, --human-readable with -l and/or -s, print human readable sizes\n" +" (e.g., 1K 234M 2G)\n" +" --si likewise, but use powers of 1000 not 1024\n" +" -H, --dereference-command-line\n" +" follow symbolic links listed on the command " +"line\n" +" --dereference-command-line-symlink-to-dir\n" +" follow each command line symbolic link\n" +" that points to a directory\n" +" --hide=PATTERN do not list implied entries matching shell " +"PATTERN\n" +" (overridden by -a or -A)\n" +" --indicator-style=WORD append indicator with style WORD to entry " +"names:\n" +" none (default), slash (-p),\n" +" file-type (--file-type), classify (-F)\n" +" -i, --inode print the index number of each file\n" +" -I, --ignore=PATTERN do not list implied entries matching shell " +"PATTERN\n" +" -k, --kibibytes default to 1024-byte blocks for disk usage\n" +" -l use a long listing format\n" +" -L, --dereference when showing file information for a symbolic\n" +" link, show information for the file the link\n" +" references rather than for the link itself\n" +" -m fill width with a comma separated list of " +"entries\n" +" -n, --numeric-uid-gid like -l, but list numeric user and group IDs\n" +" -N, --literal print raw entry names (don't treat e.g. " +"control\n" +" characters specially)\n" +" -o like -l, but do not list group information\n" +" -p, --indicator-style=slash\n" +" append / indicator to directories\n" +" -q, --hide-control-chars print ? instead of nongraphic characters\n" +" --show-control-chars show nongraphic characters as-is (the default,\n" +" unless program is 'ls' and output is a " +"terminal)\n" +" -Q, --quote-name enclose entry names in double quotes\n" +" --quoting-style=WORD use quoting style WORD for entry names:\n" +" literal, locale, shell, shell-always,\n" +" shell-escape, shell-escape-always, c, escape\n" +" -r, --reverse reverse order while sorting\n" +" -R, --recursive list subdirectories recursively\n" +" -s, --size print the allocated size of each file, in " +"blocks\n" +" -S sort by file size, largest first\n" +" --sort=WORD sort by WORD instead of name: none (-U), size (-" +"S),\n" +" time (-t), version (-v), extension (-X)\n" +" --time=WORD with -l, show time as WORD instead of default\n" +" modification time: atime or access or use (-" +"u);\n" +" ctime or status (-c); also use specified " +"time\n" +" as sort key if --sort=time (newest first)\n" +" --time-style=STYLE with -l, show times using style STYLE:\n" +" full-iso, long-iso, iso, locale, or +FORMAT;\n" +" FORMAT is interpreted like in 'date'; if " +"FORMAT\n" +" is FORMAT1FORMAT2, then FORMAT1 " +"applies\n" +" to non-recent files and FORMAT2 to recent " +"files;\n" +" if STYLE is prefixed with 'posix-', STYLE\n" +" takes effect only outside the POSIX locale\n" +" -t sort by modification time, newest first\n" +" -T, --tabsize=COLS assume tab stops at each COLS instead of 8\n" +" -u with -lt: sort by, and show, access time;\n" +" with -l: show access time and sort by name;\n" +" otherwise: sort by access time, newest first\n" +" -U do not sort; list entries in directory order\n" +" -v natural sort of (version) numbers within text\n" +" -w, --width=COLS set output width to COLS. 0 means no limit\n" +" -x list entries by lines instead of by columns\n" +" -X sort alphabetically by entry extension\n" +" -Z, --context print any security context of each file\n" +" -1 list one file per line. Avoid '\\n' with -q or " +"-b\n" +" --help display this help and exit\n" +" --version output version information and exit\n" +"\n" +"The SIZE argument is an integer and optional unit (example: 10K is " +"10*1024).\n" +"Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers of 1000).\n" +"\n" +"Using color to distinguish file types is disabled both by default and\n" +"with --color=never. With --color=auto, ls emits color codes only when\n" +"standard output is connected to a terminal. The LS_COLORS environment\n" +"variable can change the settings. Use the dircolors command to set it.\n" +"\n" +"Exit status:\n" +" 0 if OK,\n" +" 1 if minor problems (e.g., cannot access subdirectory),\n" +" 2 if serious trouble (e.g., cannot access command-line argument).\n" +"\n" +"GNU coreutils online help: \n" +"Full documentation at: \n" +"or available locally via: info '(coreutils) ls invocation'\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:323 +msgid "> ## Unsupported command-line options" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:324 +msgid "" +"> If you try to use an option (flag) that is not supported, `ls` and other " +"programs" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:325 +msgid "> will usually print an error message similar to this:" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:326 +msgid "" +">\n" +"> ~~~\n" +"> $ ls -j\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> \n" +"> ~~~\n" +"> ls: invalid option -- 'j'\n" +"> Try 'ls --help' for more information.\n" +"> ~~~" +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/02-filedir.md:336 +msgid "> {: .error}" +msgstr "" + +# header +#: shell-novice/_episodes/02-filedir.md:339 +msgid "#### The `man` command" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:341 +msgid "" +"The other way to learn about `ls` is to type \n" +"~~~\n" +"$ man ls\n" +"~~~" +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/02-filedir.md:345 +msgid "{: .bash}" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:347 +msgid "" +"This will turn your terminal into a page with a description \n" +"of the `ls` command and its options and, if you're lucky, some examples\n" +"of how to use it." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:351 +msgid "" +"To navigate through the `man` pages,\n" +"you may use the up and down arrow keys to move line-by-line,\n" +"or try the \"b\" and spacebar keys to skip up and down by a full page.\n" +"To search for a character or word in the `man` pages, \n" +"use \"/\" followed by the character or word you are searching for. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:357 +msgid "To **quit** the `man` pages, press `q`. " +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:360 +msgid "> ## Exploring More `ls` Flags" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:361 +msgid "" +">\n" +"> What does the command `ls` do when used with the `-l` and `-h` flags?\n" +">\n" +"> Some of its output is about properties that we do not cover in this lesson " +"(such\n" +"> as file permissions and ownership), but the rest should be useful\n" +"> nevertheless.\n" +">\n" +"> > ## Solution\n" +"> > The `-l` flag makes `ls` use a **l**ong listing format, showing not " +"only\n" +"> > the file/directory names but also additional information such as the " +"file size\n" +"> > and the time of its last modification. The `-h` flag makes the file " +"size\n" +"> > \"**h**uman readable\", i.e. display something like `5.3K` instead of " +"`5369`." +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/02-filedir.md:373 +#: shell-novice/_episodes/02-filedir.md:387 +#: shell-novice/_episodes/02-filedir.md:706 +#: shell-novice/_episodes/02-filedir.md:727 +#: shell-novice/_episodes/02-filedir.md:753 +#: shell-novice/_episodes/03-create.md:226 +#: shell-novice/_episodes/03-create.md:324 +#: shell-novice/_episodes/03-create.md:471 +#: shell-novice/_episodes/03-create.md:555 +#: shell-novice/_episodes/03-create.md:604 +#: shell-novice/_episodes/03-create.md:650 +#: shell-novice/_episodes/03-create.md:691 +#: shell-novice/_episodes/03-create.md:740 +#: shell-novice/_episodes/04-pipefilter.md:123 +#: shell-novice/_episodes/04-pipefilter.md:168 +#: shell-novice/_episodes/04-pipefilter.md:263 +#: shell-novice/_episodes/04-pipefilter.md:340 +#: shell-novice/_episodes/04-pipefilter.md:483 +#: shell-novice/_episodes/04-pipefilter.md:604 +#: shell-novice/_episodes/04-pipefilter.md:641 +#: shell-novice/_episodes/04-pipefilter.md:702 +#: shell-novice/_episodes/04-pipefilter.md:733 +#: shell-novice/_episodes/04-pipefilter.md:860 +#: shell-novice/_episodes/04-pipefilter.md:884 +#: shell-novice/_episodes/05-loop.md:186 shell-novice/_episodes/05-loop.md:261 +#: shell-novice/_episodes/05-loop.md:282 shell-novice/_episodes/05-loop.md:606 +#: shell-novice/_episodes/05-loop.md:633 shell-novice/_episodes/05-loop.md:685 +#: shell-novice/_episodes/05-loop.md:712 +#: shell-novice/_episodes/06-script.md:312 +#: shell-novice/_episodes/06-script.md:387 +#: shell-novice/_episodes/06-script.md:496 +#: shell-novice/_episodes/06-script.md:526 +#: shell-novice/_episodes/06-script.md:570 +#: shell-novice/_episodes/06-script.md:612 +#: shell-novice/_episodes/07-find.md:249 shell-novice/_episodes/07-find.md:338 +#: shell-novice/_episodes/07-find.md:382 shell-novice/_episodes/07-find.md:605 +#: shell-novice/_episodes/07-find.md:657 shell-novice/_episodes/07-find.md:679 +msgid "> {: .solution}" +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/02-filedir.md:374 +#: shell-novice/_episodes/02-filedir.md:388 +#: shell-novice/_episodes/02-filedir.md:707 +#: shell-novice/_episodes/02-filedir.md:728 +#: shell-novice/_episodes/02-filedir.md:754 +#: shell-novice/_episodes/03-create.md:227 +#: shell-novice/_episodes/03-create.md:325 +#: shell-novice/_episodes/03-create.md:472 +#: shell-novice/_episodes/03-create.md:556 +#: shell-novice/_episodes/03-create.md:605 +#: shell-novice/_episodes/03-create.md:651 +#: shell-novice/_episodes/03-create.md:692 +#: shell-novice/_episodes/03-create.md:741 +#: shell-novice/_episodes/04-pipefilter.md:124 +#: shell-novice/_episodes/04-pipefilter.md:169 +#: shell-novice/_episodes/04-pipefilter.md:239 +#: shell-novice/_episodes/04-pipefilter.md:264 +#: shell-novice/_episodes/04-pipefilter.md:341 +#: shell-novice/_episodes/04-pipefilter.md:484 +#: shell-novice/_episodes/04-pipefilter.md:605 +#: shell-novice/_episodes/04-pipefilter.md:642 +#: shell-novice/_episodes/04-pipefilter.md:667 +#: shell-novice/_episodes/04-pipefilter.md:703 +#: shell-novice/_episodes/04-pipefilter.md:734 +#: shell-novice/_episodes/04-pipefilter.md:861 +#: shell-novice/_episodes/04-pipefilter.md:885 +#: shell-novice/_episodes/05-loop.md:187 shell-novice/_episodes/05-loop.md:283 +#: shell-novice/_episodes/05-loop.md:607 shell-novice/_episodes/05-loop.md:634 +#: shell-novice/_episodes/05-loop.md:686 shell-novice/_episodes/05-loop.md:713 +#: shell-novice/_episodes/06-script.md:313 +#: shell-novice/_episodes/06-script.md:388 +#: shell-novice/_episodes/06-script.md:497 +#: shell-novice/_episodes/06-script.md:527 +#: shell-novice/_episodes/06-script.md:571 +#: shell-novice/_episodes/06-script.md:613 +#: shell-novice/_episodes/07-find.md:250 shell-novice/_episodes/07-find.md:339 +#: shell-novice/_episodes/07-find.md:383 shell-novice/_episodes/07-find.md:606 +#: shell-novice/_episodes/07-find.md:658 shell-novice/_episodes/07-find.md:680 +msgid "{: .challenge}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:376 +msgid "> ## Listing Recursively and By Time" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:377 +msgid "" +">\n" +"> The command `ls -R` lists the contents of directories recursively, i.e., " +"lists\n" +"> their sub-directories, sub-sub-directories, and so on at each level. The " +"command\n" +"> `ls -t` lists things by time of last change, with most recently changed " +"files or\n" +"> directories first.\n" +"> In what order does `ls -R -t` display things? Hint: `ls -l` uses a long " +"listing\n" +"> format to view timestamps.\n" +">\n" +"> > ## Solution\n" +"> > The files/directories in each directory are sorted by time of last " +"change." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:390 +msgid "" +"Here,\n" +"we can see that our home directory contains mostly **sub-directories**.\n" +"Any names in your output that don't have trailing slashes,\n" +"are plain old **files**.\n" +"And note that there is a space between `ls` and `-F`:\n" +"without it,\n" +"the shell thinks we're trying to run a command called `ls-F`,\n" +"which doesn't exist." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:399 +msgid "" +"We can also use `ls` to see the contents of a different directory. Let's " +"take a\n" +"look at our `Desktop` directory by running `ls -F Desktop`,\n" +"i.e.,\n" +"the command `ls` with the `-F` **flag** and the **argument** `Desktop`.\n" +"The argument `Desktop` tells `ls` that\n" +"we want a listing of something other than our current working directory:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:406 +msgid "" +"~~~\n" +"$ ls -F Desktop\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:411 +msgid "" +"~~~\n" +"data-shell/\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:416 +msgid "" +"Your output should be a list of all the files and sub-directories on your\n" +"Desktop, including the `data-shell` directory you downloaded at\n" +"the start of the lesson. Take a look at your Desktop to confirm that\n" +"your output is accurate. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:421 +msgid "" +"As you may now see, using a bash shell is strongly dependent on the idea " +"that\n" +"your files are organized in a hierarchical file system.\n" +"Organizing things hierarchically in this way helps us keep track of our " +"work:\n" +"it's possible to put hundreds of files in our home directory,\n" +"just as it's possible to pile hundreds of printed papers on our desk,\n" +"but it's a self-defeating strategy." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:428 +msgid "" +"Now that we know the `data-shell` directory is located on our Desktop, we\n" +"can do two things. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:431 +msgid "" +"First, we can look at its contents, using the same strategy as before, " +"passing\n" +"a directory name to `ls`:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:434 +msgid "" +"~~~\n" +"$ ls -F Desktop/data-shell\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:439 +msgid "" +"~~~\n" +"creatures/ molecules/ notes.txt solar.pdf\n" +"data/ north-pacific-gyre/ pizza.cfg writing/\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:445 +msgid "" +"Second, we can actually change our location to a different directory, so\n" +"we are no longer located in\n" +"our home directory. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:449 +msgid "" +"The command to change locations is `cd` followed by a\n" +"directory name to change our working directory.\n" +"`cd` stands for \"change directory\",\n" +"which is a bit misleading:\n" +"the command doesn't change the directory,\n" +"it changes the shell's idea of what directory we are in." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:456 +msgid "" +"Let's say we want to move to the `data` directory we saw above. We can\n" +"use the following series of commands to get there:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:459 +msgid "" +"~~~\n" +"$ cd Desktop\n" +"$ cd data-shell\n" +"$ cd data\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:466 +msgid "" +"These commands will move us from our home directory onto our Desktop, then " +"into\n" +"the `data-shell` directory, then into the `data` directory. `cd` doesn't " +"print anything,\n" +"but if we run `pwd` after it, we can see that we are now\n" +"in `/Users/nelle/Desktop/data-shell/data`.\n" +"If we run `ls` without arguments now,\n" +"it lists the contents of `/Users/nelle/Desktop/data-shell/data`,\n" +"because that's where we now are:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:479 +#: shell-novice/_episodes/02-filedir.md:652 +msgid "" +"~~~\n" +"/Users/nelle/Desktop/data-shell/data\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:489 +msgid "" +"~~~\n" +"amino-acids.txt elements/ pdb/\t salmon.txt\n" +"animals.txt morse.txt planets.txt sunspot.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:495 +msgid "" +"We now know how to go down the directory tree, but\n" +"how do we go up? We might try the following:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:498 +msgid "" +"~~~\n" +"$ cd data-shell\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:503 +msgid "" +"~~~\n" +"-bash: cd: data-shell: No such file or directory\n" +"~~~" +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/02-filedir.md:506 +#: shell-novice/_episodes/03-create.md:299 +#: shell-novice/_episodes/03-create.md:505 shell-novice/_episodes/05-loop.md:53 +msgid "{: .error}" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:508 +msgid "But we get an error! Why is this? " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:510 +msgid "" +"With our methods so far,\n" +"`cd` can only see sub-directories inside your current directory. There are\n" +"different ways to see directories above your current location; we'll start\n" +"with the simplest. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:515 +msgid "" +"There is a shortcut in the shell to move up one directory level\n" +"that looks like this:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:518 +#: shell-novice/_episodes/03-create.md:283 +msgid "" +"~~~\n" +"$ cd ..\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:523 +msgid "" +"`..` is a special directory name meaning\n" +"\"the directory containing this one\",\n" +"or more succinctly,\n" +"the **parent** of the current directory.\n" +"Sure enough,\n" +"if we run `pwd` after running `cd ..`, we're back in `/Users/nelle/Desktop/" +"data-shell`:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:535 +#: shell-novice/_episodes/03-create.md:32 +#: shell-novice/_episodes/03-create.md:355 +msgid "" +"~~~\n" +"/Users/nelle/Desktop/data-shell\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:540 +msgid "" +"The special directory `..` doesn't usually show up when we run `ls`. If we " +"want\n" +"to display it, we can give `ls` the `-a` flag:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:543 +msgid "" +"~~~\n" +"$ ls -F -a\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:548 +msgid "" +"~~~\n" +"./ .bash_profile data/ north-pacific-gyre/ pizza.cfg thesis/\n" +"../ creatures/ molecules/ notes.txt solar.pdf writing/\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:554 +msgid "" +"`-a` stands for \"show all\";\n" +"it forces `ls` to show us file and directory names that begin with `.`,\n" +"such as `..` (which, if we're in `/Users/nelle`, refers to the `/Users` " +"directory)\n" +"As you can see,\n" +"it also displays another special directory that's just called `.`,\n" +"which means \"the current working directory\".\n" +"It may seem redundant to have a name for it,\n" +"but we'll see some uses for it soon." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:563 +msgid "" +"Note that in most command line tools, multiple flags can be combined \n" +"with a single `-` and no spaces between the flags: `ls -F -a` is \n" +"equivalent to `ls -Fa`." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:567 +msgid "> ## Other Hidden Files" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:568 +msgid "" +">\n" +"> In addition to the hidden directories `..` and `.`, you may also see a " +"file\n" +"> called `.bash_profile`. This file usually contains shell configuration\n" +"> settings. You may also see other files and directories beginning\n" +"> with `.`. These are usually files and directories that are used to " +"configure\n" +"> different programs on your computer. The prefix `.` is used to prevent " +"these\n" +"> configuration files from cluttering the terminal when a standard `ls` " +"command\n" +"> is used." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:578 +msgid "> ## Orthogonality" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:579 +msgid "" +">\n" +"> The special names `.` and `..` don't belong to `cd`;\n" +"> they are interpreted the same way by every program.\n" +"> For example,\n" +"> if we are in `/Users/nelle/data`,\n" +"> the command `ls ..` will give us a listing of `/Users/nelle`.\n" +"> When the meanings of the parts are the same no matter how they're " +"combined,\n" +"> programmers say they are **orthogonal**:\n" +"> Orthogonal systems tend to be easier for people to learn\n" +"> because there are fewer special cases and exceptions to keep track of." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:591 +msgid "" +"These then, are the basic commands for navigating the filesystem on your " +"computer:\n" +"`pwd`, `ls` and `cd`. Let's explore some variations on those commands. " +"What happens\n" +"if you type `cd` on its own, without giving\n" +"a directory? " +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:596 +msgid "" +"~~~\n" +"$ cd\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:601 +msgid "How can you check what happened? `pwd` gives us the answer! " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:613 +msgid "" +"It turns out that `cd` without an argument will return you to your home " +"directory,\n" +"which is great if you've gotten lost in your own filesystem. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:616 +msgid "" +"Let's try returning to the `data` directory from before. Last time, we " +"used\n" +"three commands, but we can actually string together the list of directories\n" +"to move to `data` in one step:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:620 +msgid "" +"~~~\n" +"$ cd Desktop/data-shell/data\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:625 +msgid "" +"Check that we've moved to the right place by running `pwd` and `ls -F` " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:627 +msgid "" +"If we want to move up one level from the data directory, we could use `cd .." +"`. But\n" +"there is another way to move to any directory, regardless of your\n" +"current location. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:631 +msgid "" +"So far, when specifying directory names, or even a directory path (as " +"above),\n" +"we have been using **relative paths**. When you use a relative path with a " +"command\n" +"like `ls` or `cd`, it tries to find that location from where we are,\n" +"rather than from the root of the file system. " +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:636 +msgid "" +"However, it is possible to specify the **absolute path** to a directory by\n" +"including its entire path from the root directory, which is indicated by a\n" +"leading slash. The leading `/` tells the computer to follow the path from\n" +"the root of the file system, so it always refers to exactly one directory,\n" +"no matter where we are when we run the command." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:642 +msgid "" +"This allows us to move to our `data-shell` directory from anywhere on\n" +"the filesystem (including from inside `data`). To find the absolute path\n" +"we're looking for, we can use `pwd` and then extract the piece we need\n" +"to move to `data-shell`. " +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:657 +msgid "" +"~~~\n" +"$ cd /Users/nelle/Desktop/data-shell\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:662 +msgid "" +"Run `pwd` and `ls -F` to ensure that we're in the directory we expect. " +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:664 +msgid "> ## Two More Shortcuts" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:665 +msgid "" +">\n" +"> The shell interprets the character `~` (tilde) at the start of a path to\n" +"> mean \"the current user's home directory\". For example, if Nelle's home\n" +"> directory is `/Users/nelle`, then `~/data` is equivalent to\n" +"> `/Users/nelle/data`. This only works if it is the first character in the\n" +"> path: `here/there/~/elsewhere` is *not* `here/there/Users/nelle/" +"elsewhere`.\n" +">\n" +"> Another shortcut is the `-` (dash) character. `cd` will translate `-` " +"into\n" +"> *the previous directory I was in*, which is faster than having to " +"remember,\n" +"> then type, the full path. This is a *very* efficient way of moving back\n" +"> and forth between directories. The difference between `cd ..` and `cd -` " +"is\n" +"> that the former brings you *up*, while the latter brings you *back*. You " +"can\n" +"> think of it as the *Last Channel* button on a TV remote." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:680 +msgid "> ## Absolute vs Relative Paths" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:681 +msgid "" +">\n" +"> Starting from `/Users/amanda/data/`,\n" +"> which of the following commands could Amanda use to navigate to her home " +"directory,\n" +"> which is `/Users/amanda`?\n" +">\n" +"> 1. `cd .`\n" +"> 2. `cd /`\n" +"> 3. `cd /home/amanda`\n" +"> 4. `cd ../..`\n" +"> 5. `cd ~`\n" +"> 6. `cd home`\n" +"> 7. `cd ~/data/..`\n" +"> 8. `cd`\n" +"> 9. `cd ..`\n" +">\n" +"> > ## Solution\n" +"> > 1. No: `.` stands for the current directory.\n" +"> > 2. No: `/` stands for the root directory.\n" +"> > 3. No: Amanda's home directory is `/Users/amanda`.\n" +"> > 4. No: this goes up two levels, i.e. ends in `/Users`.\n" +"> > 5. Yes: `~` stands for the user's home directory, in this case `/Users/" +"amanda`.\n" +"> > 6. No: this would navigate into a directory `home` in the current " +"directory if it exists.\n" +"> > 7. Yes: unnecessarily complicated, but correct.\n" +"> > 8. Yes: shortcut to go back to the user's home directory.\n" +"> > 9. Yes: goes up one level." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:709 +msgid "> ## Relative Path Resolution" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:710 +msgid "" +">\n" +"> Using the filesystem diagram below, if `pwd` displays `/Users/thing`,\n" +"> what will `ls -F ../backup` display?\n" +">\n" +"> 1. `../backup: No such file or directory`\n" +"> 2. `2012-12-01 2013-01-08 2013-01-27`\n" +"> 3. `2012-12-01/ 2013-01-08/ 2013-01-27/`\n" +"> 4. `original/ pnas_final/ pnas_sub/`\n" +">\n" +"> ![File System for Challenge Questions](../fig/filesystem-challenge.svg)\n" +">\n" +"> > ## Solution\n" +"> > 1. No: there *is* a directory `backup` in `/Users`.\n" +"> > 2. No: this is the content of `Users/thing/backup`,\n" +"> > but with `..` we asked for one level further up.\n" +"> > 3. No: see previous explanation.\n" +"> > 4. Yes: `../backup/` refers to `/Users/backup/`." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:730 +msgid "> ## `ls` Reading Comprehension" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:731 +msgid "" +">\n" +"> Assuming a directory structure as in the above Figure\n" +"> (File System for Challenge Questions), if `pwd` displays `/Users/backup`,\n" +"> and `-r` tells `ls` to display things in reverse order,\n" +"> what command will display:\n" +">\n" +"> ~~~\n" +"> pnas_sub/ pnas_final/ original/\n" +"> ~~~" +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/02-filedir.md:740 +#: shell-novice/_episodes/03-create.md:569 +#: shell-novice/_episodes/03-create.md:577 +#: shell-novice/_episodes/03-create.md:619 +#: shell-novice/_episodes/03-create.md:632 +#: shell-novice/_episodes/03-create.md:640 +#: shell-novice/_episodes/03-create.md:674 +#: shell-novice/_episodes/04-pipefilter.md:323 +#: shell-novice/_episodes/04-pipefilter.md:334 +#: shell-novice/_episodes/04-pipefilter.md:630 +#: shell-novice/_episodes/04-pipefilter.md:691 +#: shell-novice/_episodes/04-pipefilter.md:716 +#: shell-novice/_episodes/05-loop.md:124 shell-novice/_episodes/05-loop.md:369 +#: shell-novice/_episodes/05-loop.md:559 shell-novice/_episodes/07-find.md:239 +#: shell-novice/_episodes/07-find.md:272 +msgid "> {: .output}" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:741 +msgid "" +">\n" +"> 1. `ls pwd`\n" +"> 2. `ls -r -F`\n" +"> 3. `ls -r -F /Users/backup`\n" +"> 4. Either #2 or #3 above, but not #1.\n" +">\n" +"> > ## Solution\n" +"> > 1. No: `pwd` is not the name of a directory.\n" +"> > 2. Yes: `ls` without directory argument lists files and directories\n" +"> > in the current directory.\n" +"> > 3. Yes: uses the absolute path explicitly.\n" +"> > 4. Correct: see explanations above." +msgstr "" + +# header +#: shell-novice/_episodes/02-filedir.md:756 +msgid "### Nelle's Pipeline: Organizing Files" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:758 +msgid "" +"Knowing just this much about files and directories,\n" +"Nelle is ready to organize the files that the protein assay machine will " +"create.\n" +"First,\n" +"she creates a directory called `north-pacific-gyre`\n" +"(to remind herself where the data came from).\n" +"Inside that,\n" +"she creates a directory called `2012-07-03`,\n" +"which is the date she started processing the samples.\n" +"She used to use names like `conference-paper` and `revised-results`,\n" +"but she found them hard to understand after a couple of years.\n" +"(The final straw was when she found herself creating\n" +"a directory called `revised-revised-results-3`.)" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/02-filedir.md:771 +msgid "> ## Sorting Output" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:772 +msgid "" +">\n" +"> Nelle names her directories \"year-month-day\",\n" +"> with leading zeroes for months and days,\n" +"> because the shell displays file and directory names in alphabetical " +"order.\n" +"> If she used month names,\n" +"> December would come before July;\n" +"> if she didn't use leading zeroes,\n" +"> November ('11') would come before July ('7'). Similarly, putting the year " +"first\n" +"> means that June 2012 will come before June 2013." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:783 +msgid "" +"Each of her physical samples is labelled according to her lab's convention\n" +"with a unique ten-character ID,\n" +"such as \"NENE01729A\".\n" +"This is what she used in her collection log\n" +"to record the location, time, depth, and other characteristics of the " +"sample,\n" +"so she decides to use it as part of each data file's name.\n" +"Since the assay machine's output is plain text,\n" +"she will call her files `NENE01729A.txt`, `NENE01812A.txt`, and so on.\n" +"All 1520 files will go into the same directory." +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:793 +msgid "" +"Now in her current directory `data-shell`,\n" +"Nelle can see what files she has using the command:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:796 +msgid "" +"~~~\n" +"$ ls north-pacific-gyre/2012-07-03/\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:801 +msgid "" +"This is a lot to type,\n" +"but she can let the shell do most of the work through what is called **tab " +"completion**.\n" +"If she types:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:805 +msgid "" +"~~~\n" +"$ ls nor\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:810 +msgid "" +"and then presses tab (the tab key on her keyboard),\n" +"the shell automatically completes the directory name for her:" +msgstr "" + +# code block +#: shell-novice/_episodes/02-filedir.md:813 +msgid "" +"~~~\n" +"$ ls north-pacific-gyre/\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/02-filedir.md:818 +msgid "" +"If she presses tab again,\n" +"Bash will add `2012-07-03/` to the command,\n" +"since it's the only possible completion.\n" +"Pressing tab again does nothing,\n" +"since there are 19 possibilities;\n" +"pressing tab twice brings up a list of all the files,\n" +"and so on.\n" +"This is called **tab completion**,\n" +"and we will see it in many other tools as we go on." +msgstr "" + +# Front Matter +#: shell-novice/_episodes/03-create.md:1 +msgid "" +"---\n" +"title: \"Working With Files and Directories\"\n" +"teaching: 25\n" +"exercises: 10\n" +"questions:\n" +"- \"How can I create, copy, and delete files and directories?\"\n" +"- \"How can I edit files?\"\n" +"objectives:\n" +"- \"Create a directory hierarchy that matches a given diagram.\"\n" +"- \"Create files in that hierarchy using an editor or by copying and " +"renaming existing files.\"\n" +"- \"Delete specified files and/or directories.\"\n" +"keypoints:\n" +"- \"`cp old new` copies a file.\"\n" +"- \"`mkdir path` creates a new directory.\"\n" +"- \"`mv old new` moves (renames) a file or directory.\"\n" +"- \"`rm path` removes (deletes) a file.\"\n" +"- \"Use of the Control key may be described in many ways, including `Ctrl-" +"X`, `Control-X`, and `^X`.\"\n" +"- \"The shell does not have a trash bin: once something is deleted, it's " +"really gone.\"\n" +"- \"Depending on the type of work you do, you may need a more powerful text " +"editor than Nano.\"\n" +"---" +msgstr "" + +#: shell-novice/_episodes/03-create.md:22 +msgid "" +"We now know how to explore files and directories,\n" +"but how do we create them in the first place?\n" +"Let's go back to our `data-shell` directory on the Desktop\n" +"and use `ls -F` to see what it contains:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:42 +msgid "" +"~~~\n" +"creatures/ data/ molecules/ north-pacific-gyre/ notes.txt pizza.cfg " +"solar.pdf writing/\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:47 +msgid "" +"Let's create a new directory called `thesis` using the command `mkdir " +"thesis`\n" +"(which has no output):" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:50 +msgid "" +"~~~\n" +"$ mkdir thesis\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:55 +msgid "" +"As you might guess from its name,\n" +"`mkdir` means \"make directory\".\n" +"Since `thesis` is a relative path\n" +"(i.e., doesn't have a leading slash),\n" +"the new directory is created in the current working directory:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:66 +msgid "" +"~~~\n" +"creatures/ data/ molecules/ north-pacific-gyre/ notes.txt pizza.cfg " +"solar.pdf thesis/ writing/\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:71 +msgid "> ## Two ways of doing the same thing" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:72 +msgid "" +"> Using the shell to create a directory is no different than using a file " +"explorer." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:73 +msgid "" +"> If you open the current directory using your operating system's graphical " +"file explorer," +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:74 +msgid "> the `thesis` directory will appear there too." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:75 +msgid "> While they are two different ways of interacting with the files," +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:76 +msgid "> the files and directories themselves are the same." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:79 +msgid "> ## Good names for files and directories" +msgstr "" + +#: shell-novice/_episodes/03-create.md:80 +msgid "" +">\n" +"> Complicated names of files and directories can make your life painful\n" +"> when working on the command line. Here we provide a few useful\n" +"> tips for the names of your files.\n" +">\n" +"> 1. Don't use whitespaces.\n" +">\n" +"> Whitespaces can make a name more meaningful\n" +"> but since whitespace is used to break arguments on the command line\n" +"> it is better to avoid them in names of files and directories.\n" +"> You can use `-` or `_` instead of whitespace.\n" +">\n" +"> 2. Don't begin the name with `-` (dash).\n" +">\n" +"> Commands treat names starting with `-` as options.\n" +">\n" +"> 3. Stick with letters, numbers, `.` (period), `-` (dash) and `_` " +"(underscore).\n" +">\n" +"> Many other characters have special meanings on the command line.\n" +"> We will learn about some of these during this lesson.\n" +"> There are special characters that can cause your command to not work " +"as\n" +"> expected and can even result in data loss.\n" +">\n" +"> If you need to refer to names of files or directories that have " +"whitespace\n" +"> or another non-alphanumeric character, you should surround the name in " +"quotes (`\"\"`)." +msgstr "" + +#: shell-novice/_episodes/03-create.md:107 +msgid "" +"Since we've just created the `thesis` directory, there's nothing in it yet:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:109 +msgid "" +"~~~\n" +"$ ls -F thesis\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:114 +msgid "" +"Let's change our working directory to `thesis` using `cd`,\n" +"then run a text editor called Nano to create a file called `draft.txt`:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:117 +msgid "" +"~~~\n" +"$ cd thesis\n" +"$ nano draft.txt\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:123 +msgid "> ## Which Editor?" +msgstr "" + +#: shell-novice/_episodes/03-create.md:124 +msgid "" +">\n" +"> When we say, \"`nano` is a text editor,\" we really do mean \"text\": it " +"can\n" +"> only work with plain character data, not tables, images, or any other\n" +"> human-friendly media. We use it in examples because it is one of the \n" +"> least complex text editors. However, because of this trait, it may \n" +"> not be powerful enough or flexible enough for the work you need to do\n" +"> after this workshop. On Unix systems (such as Linux and Mac OS X),\n" +"> many programmers use [Emacs](http://www.gnu.org/software/emacs/) or\n" +"> [Vim](http://www.vim.org/) (both of which require more time to learn), \n" +"> or a graphical editor such as\n" +"> [Gedit](http://projects.gnome.org/gedit/). On Windows, you may wish to\n" +"> use [Notepad++](http://notepad-plus-plus.org/). Windows also has a built-" +"in\n" +"> editor called `notepad` that can be run from the command line in the same\n" +"> way as `nano` for the purposes of this lesson. \n" +">\n" +"> No matter what editor you use, you will need to know where it searches\n" +"> for and saves files. If you start it from the shell, it will (probably)\n" +"> use your current working directory as its default location. If you use\n" +"> your computer's start menu, it may want to save files in your desktop or\n" +"> documents directory instead. You can change this by navigating to\n" +"> another directory the first time you \"Save As...\"" +msgstr "" + +#: shell-novice/_episodes/03-create.md:147 +msgid "" +"Let's type in a few lines of text.\n" +"Once we're happy with our text, we can press `Ctrl-O` (press the Ctrl or " +"Control key and, while\n" +"holding it down, press the O key) to write our data to disk\n" +"(we'll be asked what file we want to save this to:\n" +"press Return to accept the suggested default of `draft.txt`)." +msgstr "" + +#: shell-novice/_episodes/03-create.md:153 +msgid "![Nano in Action](../fig/nano-screenshot.png)" +msgstr "" + +#: shell-novice/_episodes/03-create.md:155 +msgid "" +"Once our file is saved, we can use `Ctrl-X` to quit the editor and\n" +"return to the shell." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:158 +msgid "> ## Control, Ctrl, or ^ Key" +msgstr "" + +#: shell-novice/_episodes/03-create.md:159 +msgid "" +">\n" +"> The Control key is also called the \"Ctrl\" key. There are various ways\n" +"> in which using the Control key may be described. For example, you may\n" +"> see an instruction to press the Control key and, while holding it down,\n" +"> press the X key, described as any of:\n" +">\n" +"> * `Control-X`\n" +"> * `Control+X`\n" +"> * `Ctrl-X`\n" +"> * `Ctrl+X`\n" +"> * `^X`\n" +"> * `C-x`\n" +">\n" +"> In nano, along the bottom of the screen you'll see `^G Get Help ^O " +"WriteOut`.\n" +"> This means that you can use `Control-G` to get help and `Control-O` to " +"save your\n" +"> file." +msgstr "" + +#: shell-novice/_episodes/03-create.md:177 +msgid "" +"`nano` doesn't leave any output on the screen after it exits,\n" +"but `ls` now shows that we have created a file called `draft.txt`:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:185 +#: shell-novice/_episodes/03-create.md:278 +#: shell-novice/_episodes/03-create.md:367 +msgid "" +"~~~\n" +"draft.txt\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:190 +msgid "> ## Creating Files a Different Way" +msgstr "" + +#: shell-novice/_episodes/03-create.md:191 +msgid "" +">\n" +"> We have seen how to create text files using the `nano` editor.\n" +"> Now, try the following command in your home directory:\n" +">\n" +"> ~~~\n" +"> $ cd # go to your home directory\n" +"> $ touch my_file.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> 1. What did the touch command do?\n" +"> When you look at your home directory using the GUI file explorer,\n" +"> does the file show up?\n" +">\n" +"> 2. Use `ls -l` to inspect the files. How large is `my_file.txt`?\n" +">\n" +"> 3. When might you want to create a file this way?\n" +">\n" +"> > ## Solution\n" +"> > 1. The touch command generates a new file called 'my_file.txt' in\n" +"> > your home directory. If you are in your home directory, you\n" +"> > can observe this newly generated file by typing 'ls' at the \n" +"> > command line prompt. 'my_file.txt' can also be viewed in your\n" +"> > GUI file explorer.\n" +"> >\n" +"> > 2. When you inspect the file with 'ls -l', note that the size of\n" +"> > 'my_file.txt' is 0kb. In other words, it contains no data.\n" +"> > If you open 'my_file.txt' using your text editor it is blank.\n" +"> >\n" +"> > 3. Some programs do not generate output files themselves, but\n" +"> > instead require that empty files have already been generated.\n" +"> > When the program is run, it searches for an existing file to\n" +"> > populate with its output. The touch command allows you to\n" +"> > efficiently generate a blank text file to be used by such\n" +"> > programs." +msgstr "" + +#: shell-novice/_episodes/03-create.md:229 +msgid "" +"Returning to the `data-shell` directory,\n" +"let's tidy up the `thesis` directory by removing the draft we created:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:232 +msgid "" +"~~~\n" +"$ cd thesis\n" +"$ rm draft.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:238 +msgid "" +"This command removes files (`rm` is short for \"remove\").\n" +"If we run `ls` again,\n" +"its output is empty once more,\n" +"which tells us that our file is gone:" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:248 +msgid "> ## Deleting Is Forever" +msgstr "" + +#: shell-novice/_episodes/03-create.md:249 +msgid "" +">\n" +"> The Unix shell doesn't have a trash bin that we can recover deleted\n" +"> files from (though most graphical interfaces to Unix do). Instead,\n" +"> when we delete files, they are unhooked from the file system so that\n" +"> their storage space on disk can be recycled. Tools for finding and\n" +"> recovering deleted files do exist, but there's no guarantee they'll\n" +"> work in any particular situation, since the computer may recycle the\n" +"> file's disk space right away." +msgstr "" + +#: shell-novice/_episodes/03-create.md:259 +msgid "" +"Let's re-create that file\n" +"and then move up one directory to `/Users/nelle/Desktop/data-shell` using " +"`cd ..`:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:267 +msgid "" +"~~~\n" +"/Users/nelle/Desktop/data-shell/thesis\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:272 +msgid "" +"~~~\n" +"$ nano draft.txt\n" +"$ ls\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:288 +msgid "" +"If we try to remove the entire `thesis` directory using `rm thesis`,\n" +"we get an error message:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:291 +msgid "" +"~~~\n" +"$ rm thesis\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:296 +msgid "" +"~~~\n" +"rm: cannot remove `thesis': Is a directory\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:301 +msgid "" +"This happens because `rm` by default only works on files, not directories." +msgstr "" + +#: shell-novice/_episodes/03-create.md:303 +msgid "" +"To really get rid of `thesis` we must also delete the file `draft.txt`.\n" +"We can do this with the [recursive](https://en.wikipedia.org/wiki/Recursion) " +"option for `rm`:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:306 +msgid "" +"~~~\n" +"$ rm -r thesis\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:311 +msgid "> ## Using `rm` Safely" +msgstr "" + +#: shell-novice/_episodes/03-create.md:312 +msgid "" +">\n" +"> What happens when we type `rm -i thesis/quotations.txt`?\n" +"> Why would we want this protection when using `rm`?\n" +">\n" +"> > ## Solution\n" +"> > ```\n" +"> > $ rm: remove regular file 'thesis/quotations.txt'?\n" +"> > ```\n" +"> > {: .language-bash} \n" +"> > The -i option will prompt before every removal. \n" +"> > The Unix shell doesn't have a trash bin, so all the files removed will " +"disappear forever. \n" +"> > By using the -i flag, we have the chance to check that we are deleting " +"only the files that we want to remove." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:327 +msgid "> ## With Great Power Comes Great Responsibility" +msgstr "" + +#: shell-novice/_episodes/03-create.md:328 +msgid "" +">\n" +"> Removing the files in a directory recursively can be a very dangerous\n" +"> operation. If we're concerned about what we might be deleting we can\n" +"> add the \"interactive\" flag `-i` to `rm` which will ask us for " +"confirmation\n" +"> before each step\n" +">\n" +"> ~~~\n" +"> $ rm -r -i thesis\n" +"> rm: descend into directory ‘thesis’? y\n" +"> rm: remove regular file ‘thesis/draft.txt’? y\n" +"> rm: remove directory ‘thesis’? y\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> This removes everything in the directory, then the directory itself, " +"asking\n" +"> at each step for you to confirm the deletion." +msgstr "" + +#: shell-novice/_episodes/03-create.md:346 +msgid "" +"Let's create that directory and file one more time.\n" +"(Note that this time we're running `nano` with the path `thesis/draft.txt`,\n" +"rather than going into the `thesis` directory and running `nano` on `draft." +"txt` there.)" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:360 +msgid "" +"~~~\n" +"$ mkdir thesis\n" +"$ nano thesis/draft.txt\n" +"$ ls thesis\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:372 +msgid "" +"`draft.txt` isn't a particularly informative name,\n" +"so let's change the file's name using `mv`,\n" +"which is short for \"move\":" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:376 +msgid "" +"~~~\n" +"$ mv thesis/draft.txt thesis/quotes.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:381 +msgid "" +"The first argument tells `mv` what we're \"moving\",\n" +"while the second is where it's to go.\n" +"In this case,\n" +"we're moving `thesis/draft.txt` to `thesis/quotes.txt`,\n" +"which has the same effect as renaming the file.\n" +"Sure enough,\n" +"`ls` shows us that `thesis` now contains one file called `quotes.txt`:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:389 +#: shell-novice/_episodes/03-create.md:424 +msgid "" +"~~~\n" +"$ ls thesis\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:394 +#: shell-novice/_episodes/03-create.md:438 +msgid "" +"~~~\n" +"quotes.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:399 +msgid "" +"One has to be careful when specifying the target file name, since `mv` will\n" +"silently overwrite any existing file with the same name, which could\n" +"lead to data loss. An additional flag, `mv -i` (or `mv --interactive`),\n" +"can be used to make `mv` ask you for confirmation before overwriting." +msgstr "" + +#: shell-novice/_episodes/03-create.md:404 +msgid "" +"Just for the sake of consistency,\n" +"`mv` also works on directories" +msgstr "" + +#: shell-novice/_episodes/03-create.md:407 +msgid "" +"Let's move `quotes.txt` into the current working directory.\n" +"We use `mv` once again,\n" +"but this time we'll just use the name of a directory as the second argument\n" +"to tell `mv` that we want to keep the filename,\n" +"but put the file somewhere new.\n" +"(This is why the command is called \"move\".)\n" +"In this case,\n" +"the directory name we use is the special directory name `.` that we " +"mentioned earlier." +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:416 +msgid "" +"~~~\n" +"$ mv thesis/quotes.txt .\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:421 +msgid "" +"The effect is to move the file from the directory it was in to the current " +"working directory.\n" +"`ls` now shows us that `thesis` is empty:" +msgstr "" + +#: shell-novice/_episodes/03-create.md:429 +msgid "" +"Further,\n" +"`ls` with a filename or directory name as an argument only lists that file " +"or directory.\n" +"We can use this to see that `quotes.txt` is still in our current directory:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:433 +msgid "" +"~~~\n" +"$ ls quotes.txt\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:443 +msgid "> ## Moving to the Current Folder" +msgstr "" + +#: shell-novice/_episodes/03-create.md:444 +msgid "" +">\n" +"> After running the following commands,\n" +"> Jamie realizes that she put the files `sucrose.dat` and `maltose.dat` into " +"the wrong folder:\n" +">\n" +"> ~~~\n" +"> $ ls -F\n" +"> analyzed/ raw/\n" +"> $ ls -F analyzed\n" +"> fructose.dat glucose.dat maltose.dat sucrose.dat\n" +"> $ cd raw/\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Fill in the blanks to move these files to the current folder\n" +"> (i.e., the one she is currently in):\n" +">\n" +"> ~~~\n" +"> $ mv ___/sucrose.dat ___/maltose.dat ___\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> > ## Solution\n" +"> > ```\n" +"> > $ mv ../analyzed/sucrose.dat ../analyzed/maltose.dat .\n" +"> > ```\n" +"> > {: .language-bash}\n" +"> > Recall that `..` refers to the parent directory (i.e. one above the " +"current directory)\n" +"> > and that `.` refers to the current directory." +msgstr "" + +#: shell-novice/_episodes/03-create.md:474 +msgid "" +"The `cp` command works very much like `mv`,\n" +"except it copies a file instead of moving it.\n" +"We can check that it did the right thing using `ls`\n" +"with two paths as arguments --- like most Unix commands,\n" +"`ls` can be given multiple paths at once:" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:480 +msgid "" +"~~~\n" +"$ cp quotes.txt thesis/quotations.txt\n" +"$ ls quotes.txt thesis/quotations.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:486 +msgid "" +"~~~\n" +"quotes.txt thesis/quotations.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:491 +msgid "" +"To prove that we made a copy,\n" +"let's delete the `quotes.txt` file in the current directory\n" +"and then run that same `ls` again." +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:495 +msgid "" +"~~~\n" +"$ rm quotes.txt\n" +"$ ls quotes.txt thesis/quotations.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/03-create.md:501 +msgid "" +"~~~\n" +"ls: cannot access quotes.txt: No such file or directory\n" +"thesis/quotations.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:507 +msgid "" +"This time it tells us that it can't find `quotes.txt` in the current " +"directory,\n" +"but it does find the copy in `thesis` that we didn't delete." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:510 +msgid "> ## What's In A Name?" +msgstr "" + +#: shell-novice/_episodes/03-create.md:511 +msgid "" +">\n" +"> You may have noticed that all of Nelle's files' names are \"something dot\n" +"> something\", and in this part of the lesson, we always used the extension\n" +"> `.txt`. This is just a convention: we can call a file `mythesis` or\n" +"> almost anything else we want. However, most people use two-part names\n" +"> most of the time to help them (and their programs) tell different kinds\n" +"> of files apart. The second part of such a name is called the\n" +"> **filename extension**, and indicates\n" +"> what type of data the file holds: `.txt` signals a plain text file, `." +"pdf`\n" +"> indicates a PDF document, `.cfg` is a configuration file full of " +"parameters\n" +"> for some program or other, `.png` is a PNG image, and so on.\n" +">\n" +"> This is just a convention, albeit an important one. Files contain\n" +"> bytes: it's up to us and our programs to interpret those bytes\n" +"> according to the rules for plain text files, PDF documents, configuration\n" +"> files, images, and so on.\n" +">\n" +"> Naming a PNG image of a whale as `whale.mp3` doesn't somehow\n" +"> magically turn it into a recording of whalesong, though it *might*\n" +"> cause the operating system to try to open it with a music player\n" +"> when someone double-clicks it." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:534 +msgid "> ## Renaming Files" +msgstr "" + +#: shell-novice/_episodes/03-create.md:535 +msgid "" +">\n" +"> Suppose that you created a `.txt` file in your current directory to " +"contain a list of the\n" +"> statistical tests you will need to do to analyze your data, and named it: " +"`statstics.txt`\n" +">\n" +"> After creating and saving this file you realize you misspelled the " +"filename! You want to\n" +"> correct the mistake, which of the following commands could you use to do " +"so?\n" +">\n" +"> 1. `cp statstics.txt statistics.txt`\n" +"> 2. `mv statstics.txt statistics.txt`\n" +"> 3. `mv statstics.txt .`\n" +"> 4. `cp statstics.txt .`\n" +">\n" +"> > ## Solution\n" +"> > 1. No. While this would create a file with the correct name, the " +"incorrectly named file still exists in the directory\n" +"> > and would need to be deleted.\n" +"> > 2. Yes, this would work to rename the file.\n" +"> > 3. No, the period(.) indicates where to move the file, but does not " +"provide a new file name; identical file names\n" +"> > cannot be created.\n" +"> > 4. No, the period(.) indicates where to copy the file, but does not " +"provide a new file name; identical file names\n" +"> > cannot be created." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:558 +msgid "> ## Moving and Copying" +msgstr "" + +#: shell-novice/_episodes/03-create.md:559 +msgid "" +">\n" +"> What is the output of the closing `ls` command in the sequence shown " +"below?\n" +">\n" +"> ~~~\n" +"> $ pwd\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> ~~~\n" +"> /Users/jamie/data\n" +"> ~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:571 +#: shell-novice/_episodes/03-create.md:582 +msgid "> $ ls" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:575 +msgid "> proteins.dat" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:579 +msgid "> $ mkdir recombine" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:580 +msgid "> $ mv proteins.dat recombine/" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:581 +msgid "> $ cp recombine/proteins.dat ../proteins-saved.dat" +msgstr "" + +#: shell-novice/_episodes/03-create.md:585 +msgid "" +">\n" +"> 1. `proteins-saved.dat recombine`\n" +"> 2. `recombine`\n" +"> 3. `proteins.dat recombine`\n" +"> 4. `proteins-saved.dat`\n" +">\n" +"> > ## Solution\n" +"> > We start in the `/Users/jamie/data` directory, and create a new folder " +"called `recombine`.\n" +"> > The second line moves (`mv`) the file `proteins.dat` to the new folder " +"(`recombine`).\n" +"> > The third line makes a copy of the file we just moved. The tricky part " +"here is where the file was\n" +"> > copied to. Recall that `..` means \"go up a level\", so the copied file " +"is now in `/Users/jamie`.\n" +"> > Notice that `..` is interpreted with respect to the current working\n" +"> > directory, **not** with respect to the location of the file being " +"copied.\n" +"> > So, the only thing that will show using ls (in `/Users/jamie/data`) is " +"the recombine folder.\n" +"> >\n" +"> > 1. No, see explanation above. `proteins-saved.dat` is located at `/" +"Users/jamie`\n" +"> > 2. Yes\n" +"> > 3. No, see explanation above. `proteins.dat` is located at `/Users/" +"jamie/data/recombine`\n" +"> > 4. No, see explanation above. `proteins-saved.dat` is located at `/" +"Users/jamie`" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:607 +msgid "> ## Organizing Directories and Files" +msgstr "" + +#: shell-novice/_episodes/03-create.md:608 +msgid "" +">\n" +"> Jamie is working on a project and she sees that her files aren't very " +"well\n" +"> organized:\n" +">\n" +"> ~~~\n" +"> $ ls -F\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> ~~~\n" +"> analyzed/ fructose.dat raw/ sucrose.dat\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/03-create.md:620 +msgid "" +">\n" +"> The `fructose.dat` and `sucrose.dat` files contain output from her data\n" +"> analysis. What command(s) covered in this lesson does she need to run so " +"that the commands below will\n" +"> produce the output shown?\n" +">\n" +"> ~~~\n" +"> $ ls -F\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> ~~~\n" +"> analyzed/ raw/\n" +"> ~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:634 +msgid "> $ ls analyzed" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:638 +msgid "> fructose.dat sucrose.dat" +msgstr "" + +#: shell-novice/_episodes/03-create.md:641 +msgid "" +">\n" +"> > ## Solution\n" +"> > ```\n" +"> > mv *.dat analyzed\n" +"> > ```\n" +"> > {: .language-bash}\n" +"> > Jamie needs to move her files `fructose.dat` and `sucrose.dat` to the " +"`analyzed` directory.\n" +"> > The shell will expand *.dat to match all .dat files in the current " +"directory.\n" +"> > The `mv` command then moves the list of .dat files to the \"analyzed\" " +"directory." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:653 +msgid "> ## Copy with Multiple Filenames" +msgstr "" + +#: shell-novice/_episodes/03-create.md:654 +msgid "" +">\n" +"> For this exercise, you can test the commands in the `data-shell/data " +"directory`.\n" +">\n" +"> In the example below, what does `cp` do when given several filenames and a " +"directory name?\n" +">\n" +"> ~~~\n" +"> $ mkdir backup\n" +"> $ cp amino-acids.txt animals.txt backup/\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> In the example below, what does `cp` do when given three or more file " +"names?\n" +">\n" +"> ~~~\n" +"> $ ls -F\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> ~~~\n" +"> amino-acids.txt animals.txt backup/ elements/ morse.txt pdb/ planets." +"txt salmon.txt sunspot.txt\n" +"> ~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:676 +msgid "> $ cp amino-acids.txt animals.txt morse.txt " +msgstr "" + +#: shell-novice/_episodes/03-create.md:679 +msgid "" +">\n" +"> > ## Solution\n" +"> > If given more than one file name followed by a directory name (i.e. the " +"destination directory must \n" +"> > be the last argument), `cp` copies the files to the named directory.\n" +"> >\n" +"> > If given three file names, `cp` throws an error because it is expecting " +"a directory\n" +"> > name as the last argument.\n" +"> >\n" +"> > ```\n" +"> > cp: target ‘morse.txt’ is not a directory\n" +"> > ```\n" +"> > {: .output}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/03-create.md:694 +msgid "> ## Copy a folder structure sans files" +msgstr "" + +#: shell-novice/_episodes/03-create.md:695 +msgid "" +">\n" +"> You're starting a new experiment, and would like to duplicate the file\n" +"> structure from your previous experiment without the data files so you can\n" +"> add new data.\n" +">\n" +"> Assume that the file structure is in a folder called '2016-05-18-data',\n" +"> which contains a `data` folder that in turn contains folders named `raw` " +"and\n" +"> `processed` that contain data files. The goal is to copy the file " +"structure\n" +"> of the `2016-05-18-data` folder into a folder called `2016-05-20-data` " +"and\n" +"> remove the data files from the directory you just created.\n" +">\n" +"> Which of the following set of commands would achieve this objective?\n" +"> What would the other commands do?\n" +">\n" +"> ~~~\n" +"> $ cp -r 2016-05-18-data/ 2016-05-20-data/\n" +"> $ rm 2016-05-20-data/raw/*\n" +"> $ rm 2016-05-20-data/processed/*\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> ~~~\n" +"> $ rm 2016-05-20-data/raw/*\n" +"> $ rm 2016-05-20-data/processed/*\n" +"> $ cp -r 2016-05-18-data/ 2016-5-20-data/\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> ~~~\n" +"> $ cp -r 2016-05-18-data/ 2016-05-20-data/\n" +"> $ rm -r -i 2016-05-20-data/\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> >\n" +"> > ## Solution\n" +"> > The first set of commands achieves this objective.\n" +"> > First we have a recursive copy of a data folder.\n" +"> > Then two `rm` commands which remove all files in the specified " +"directories.\n" +"> > The shell expands the '*' wild card to match all files and " +"subdirectories.\n" +"> >\n" +"> > The second set of commands have the wrong order: \n" +"> > attempting to delete files which haven't yet been copied,\n" +"> > followed by the recursive copy command which would copy them.\n" +"> >\n" +"> > The third set of commands would achieve the objective, but in a time-" +"consuming way:\n" +"> > the first command copies the directory recursively, but the second " +"command deletes\n" +"> > interactively, prompting for confirmation for each file and directory." +msgstr "" + +# Front Matter +#: shell-novice/_episodes/04-pipefilter.md:1 +msgid "" +"---\n" +"title: \"Pipes and Filters\"\n" +"teaching: 30\n" +"exercises: 20\n" +"questions:\n" +"- \"How can I combine existing commands to do new things?\"\n" +"objectives:\n" +"- \"Redirect a command's output to a file.\"\n" +"- \"Process a file instead of keyboard input using redirection.\"\n" +"- \"Construct command pipelines with two or more stages.\"\n" +"- \"Explain what usually happens if a program or pipeline isn't given any " +"input to process.\"\n" +"- \"Explain Unix's 'small pieces, loosely joined' philosophy.\"\n" +"keypoints:\n" +"- \"`cat` displays the contents of its inputs.\"\n" +"- \"`head` displays the first few lines of its input.\"\n" +"- \"`tail` displays the last few lines of its input.\"\n" +"- \"`sort` sorts its inputs.\"\n" +"- \"`wc` counts lines, words, and characters in its inputs.\"\n" +"- \"`*` matches zero or more characters in a filename, so `*.txt` matches " +"all files ending in `.txt`.\"\n" +"- \"`?` matches any single character in a filename, so `?.txt` matches `a." +"txt` but not `any.txt`.\"\n" +"- \"`command > file` redirects a command's output to a file.\"\n" +"- \"`first | second` is a pipeline: the output of the first command is used " +"as the input to the second.\"\n" +"- \"The best way to use the shell is to use pipes to combine simple single-" +"purpose programs (filters).\"\n" +"---" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:26 +msgid "" +"Now that we know a few basic commands,\n" +"we can finally look at the shell's most powerful feature:\n" +"the ease with which it lets us combine existing programs in new ways.\n" +"We'll start with a directory called `molecules`\n" +"that contains six files describing some simple organic molecules.\n" +"The `.pdb` extension indicates that these files are in Protein Data Bank " +"format,\n" +"a simple text format that specifies the type and position of each atom in " +"the molecule." +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:34 +msgid "" +"~~~\n" +"$ ls molecules\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:39 +msgid "" +"~~~\n" +"cubane.pdb ethane.pdb methane.pdb\n" +"octane.pdb pentane.pdb propane.pdb\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:45 +msgid "" +"Let's go into that directory with `cd` and run the command `wc *.pdb`.\n" +"`wc` is the \"word count\" command:\n" +"it counts the number of lines, words, and characters in files.\n" +"The `*` in `*.pdb` matches zero or more characters,\n" +"so the shell turns `*.pdb` into a list of all `.pdb` files in the current " +"directory:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:51 +msgid "" +"~~~\n" +"$ cd molecules\n" +"$ wc *.pdb\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:57 +msgid "" +"~~~\n" +" 20 156 1158 cubane.pdb\n" +" 12 84 622 ethane.pdb\n" +" 9 57 422 methane.pdb\n" +" 30 246 1828 octane.pdb\n" +" 21 165 1226 pentane.pdb\n" +" 15 111 825 propane.pdb\n" +" 107 819 6081 total\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:68 +#: shell-novice/_episodes/07-find.md:252 +msgid "> ## Wildcards" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:69 +msgid "" +">\n" +"> `*` is a **wildcard**. It matches zero or more\n" +"> characters, so `*.pdb` matches `ethane.pdb`, `propane.pdb`, and every\n" +"> file that ends with '.pdb'. On the other hand, `p*.pdb` only matches\n" +"> `pentane.pdb` and `propane.pdb`, because the 'p' at the front only\n" +"> matches filenames that begin with the letter 'p'.\n" +">\n" +"> `?` is also a wildcard, but it only matches a single character. This\n" +"> means that `p?.pdb` would match `pi.pdb` or `p5.pdb` (if we had these two\n" +"> files in the `molecules` directory), but not `propane.pdb`.\n" +"> We can use any number of wildcards at a time: for example, `p*.p?*`\n" +"> matches anything that starts with a 'p' and ends with '.', 'p', and at\n" +"> least one more character (since the `?` has to match one character, and\n" +"> the final `*` can match any number of characters). Thus, `p*.p?*` would\n" +"> match `preferred.practice`, and even `p.pi` (since the first `*` can\n" +"> match no characters at all), but not `quality.practice` (doesn't start\n" +"> with 'p') or `preferred.p` (there isn't at least one character after the\n" +"> '.p').\n" +">\n" +"> When the shell sees a wildcard, it expands the wildcard to create a\n" +"> list of matching filenames *before* running the command that was\n" +"> asked for. As an exception, if a wildcard expression does not match\n" +"> any file, Bash will pass the expression as an argument to the command\n" +"> as it is. For example typing `ls *.pdf` in the `molecules` directory\n" +"> (which contains only files with names ending with `.pdb`) results in\n" +"> an error message that there is no file called `*.pdf`.\n" +"> However, generally commands like `wc` and `ls` see the lists of\n" +"> file names matching these expressions, but not the wildcards\n" +"> themselves. It is the shell, not the other programs, that deals with\n" +"> expanding wildcards, and this is another example of orthogonal design." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:101 +msgid "> ## Using Wildcards" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:102 +msgid "" +">\n" +"> When run in the `molecules` directory, which `ls` command(s) will\n" +"> produce this output?\n" +">\n" +"> `ethane.pdb methane.pdb`\n" +">\n" +"> 1. `ls *t*ane.pdb`\n" +"> 2. `ls *t?ne.*`\n" +"> 3. `ls *t??ne.pdb`\n" +"> 4. `ls ethane.*`\n" +">\n" +"> > ## Solution\n" +">> The solution is `3.`\n" +">>\n" +">> `1.` shows all files that contain any number and combination of " +"characters, followed by the letter `t`, another single character, and end " +"with `ane.pdb`. This includes `octane.pdb` and `pentane.pdb`. \n" +">>\n" +">> `2.` shows all files containing any number and combination of characters, " +"`t`, another single character, `ne.` followed by any number and combination " +"of characters. This will give us `octane.pdb` and `pentane.pdb` but doesn't " +"match anything which ends in `thane.pdb`.\n" +">>\n" +">> `3.` fixes the problems of option 2 by matching two characters between " +"`t` and `ne`. This is the solution.\n" +">>\n" +">> `4.` only shows files starting with `ethane.`." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:126 +msgid "> ## More on Wildcards" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:127 +msgid "" +">\n" +"> Sam has a directory containing calibration data, datasets, and " +"descriptions of\n" +"> the datasets:\n" +">\n" +"> ~~~\n" +"> 2015-10-23-calibration.txt\n" +"> 2015-10-23-dataset1.txt\n" +"> 2015-10-23-dataset2.txt\n" +"> 2015-10-23-dataset_overview.txt\n" +"> 2015-10-26-calibration.txt\n" +"> 2015-10-26-dataset1.txt\n" +"> 2015-10-26-dataset2.txt\n" +"> 2015-10-26-dataset_overview.txt\n" +"> 2015-11-23-calibration.txt\n" +"> 2015-11-23-dataset1.txt\n" +"> 2015-11-23-dataset2.txt\n" +"> 2015-11-23-dataset_overview.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Before heading off to another field trip, she wants to back up her data " +"and\n" +"> send some datasets to her colleague Bob. Sam uses the following commands\n" +"> to get the job done:\n" +">\n" +"> ~~~\n" +"> $ cp *dataset* /backup/datasets\n" +"> $ cp ____calibration____ /backup/calibration\n" +"> $ cp 2015-____-____ ~/send_to_bob/all_november_files/\n" +"> $ cp ____ ~/send_to_bob/all_datasets_created_on_a_23rd/\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Help Sam by filling in the blanks.\n" +">\n" +"> > ## Solution\n" +"> > ```\n" +"> > $ cp *calibration.txt /backup/calibration\n" +"> > $ cp 2015-11-* ~/send_to_bob/all_november_files/\n" +"> > $ cp *-23-dataset* ~send_to_bob/all_datasets_created_on_a_23rd/\n" +"> > ```\n" +"> > {: .language-bash}" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:171 +msgid "" +"If we run `wc -l` instead of just `wc`,\n" +"the output shows only the number of lines per file:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:174 +msgid "" +"~~~\n" +"$ wc -l *.pdb\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:179 +#: shell-novice/_episodes/04-pipefilter.md:277 +msgid "" +"~~~\n" +" 20 cubane.pdb\n" +" 12 ethane.pdb\n" +" 9 methane.pdb\n" +" 30 octane.pdb\n" +" 21 pentane.pdb\n" +" 15 propane.pdb\n" +" 107 total\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:190 +msgid "" +"We can also use `-w` to get only the number of words,\n" +"or `-c` to get only the number of characters." +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:193 +msgid "" +"Which of these files is shortest?\n" +"It's an easy question to answer when there are only six files,\n" +"but what if there were 6000?\n" +"Our first step toward a solution is to run the command:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:198 +msgid "" +"~~~\n" +"$ wc -l *.pdb > lengths.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:203 +msgid "" +"The greater than symbol, `>`, tells the shell to **redirect** the command's " +"output\n" +"to a file instead of printing it to the screen. (This is why there is no " +"screen output:\n" +"everything that `wc` would have printed has gone into the\n" +"file `lengths.txt` instead.) The shell will create\n" +"the file if it doesn't exist. If the file exists, it will be\n" +"silently overwritten, which may lead to data loss and thus requires\n" +"some caution.\n" +"`ls lengths.txt` confirms that the file exists:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:212 +msgid "" +"~~~\n" +"$ ls lengths.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:217 +msgid "" +"~~~\n" +"lengths.txt\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:222 +msgid "> ## What Does `>>` Mean?" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:223 +msgid "" +">\n" +"> What is the difference between:\n" +">\n" +"> ~~~\n" +"> $ echo hello > testfile01.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> and:\n" +">\n" +"> ~~~\n" +"> $ echo hello >> testfile02.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Hint: Try executing each command twice in a row and then examining the " +"output files." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:241 +msgid "> ## Appending Data" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:242 +msgid "" +">\n" +"> Consider the file `data-shell/data/animals.txt`.\n" +"> After these commands, select the answer that\n" +"> corresponds to the file `animalsUpd.txt`:\n" +">\n" +"> ~~~\n" +"> $ head -3 animals.txt > animalsUpd.txt\n" +"> $ tail -2 animals.txt >> animalsUpd.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> 1. The first three lines of `animals.txt`\n" +"> 2. The last two lines of `animals.txt`\n" +"> 3. The first three lines and the last two lines of `animals.txt`\n" +"> 4. The second and third lines of `animals.txt`\n" +">\n" +"> > ## Solution\n" +"> > Option 3 is correct. \n" +"> > For option 1 to be correct we would only run the `head` command.\n" +"> > For option 2 to be correct we would only run the `tail` command.\n" +"> > For option 4 to be correct we would have to pipe the output of `head` " +"into `tail -2` by doing `head -3 animals.txt | tail -2 >> animalsUpd.txt`" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:266 +msgid "" +"We can now send the content of `lengths.txt` to the screen using `cat " +"lengths.txt`.\n" +"`cat` stands for \"concatenate\":\n" +"it prints the contents of files one after another.\n" +"There's only one file in this case,\n" +"so `cat` just shows us what it contains:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:272 +msgid "" +"~~~\n" +"$ cat lengths.txt\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:288 +msgid "> ## Output Page by Page" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:289 +msgid "" +">\n" +"> We'll continue to use `cat` in this lesson, for convenience and " +"consistency,\n" +"> but it has the disadvantage that it always dumps the whole file onto your " +"screen.\n" +"> More useful in practice is the command `less`,\n" +"> which you use with `$ less lengths.txt`.\n" +"> This displays a screenful of the file, and then stops.\n" +"> You can go forward one screenful by pressing the spacebar,\n" +"> or back one by pressing `b`. Press `q` to quit." +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:299 +msgid "Now let's use the `sort` command to sort its contents." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:301 +msgid "> ## What Does `sort -n` Do?" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:302 +msgid "" +">\n" +"> If we run `sort` on a file containing the following lines:\n" +">\n" +"> ~~~\n" +"> 10\n" +"> 2\n" +"> 19\n" +"> 22\n" +"> 6\n" +"> ~~~" +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/04-pipefilter.md:312 +#: shell-novice/_episodes/04-pipefilter.md:620 +#: shell-novice/_episodes/04-pipefilter.md:658 +#: shell-novice/_episodes/05-loop.md:348 +#: shell-novice/_episodes/06-script.md:288 +#: shell-novice/_episodes/07-find.md:294 shell-novice/_episodes/07-find.md:305 +msgid "> {: .source}" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:313 +msgid "" +">\n" +"> the output is:\n" +">\n" +"> ~~~\n" +"> 10\n" +"> 19\n" +"> 2\n" +"> 22\n" +"> 6\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:324 +msgid "" +">\n" +"> If we run `sort -n` on the same input, we get this instead:\n" +">\n" +"> ~~~\n" +"> 2\n" +"> 6\n" +"> 10\n" +"> 19\n" +"> 22\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:335 +msgid "" +">\n" +"> Explain why `-n` has this effect.\n" +">\n" +"> > ## Solution\n" +"> > The `-n` flag specifies a numeric sort, rather than alphabetical." +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:343 +msgid "" +"We will also use the `-n` flag to specify that the sort is\n" +"numerical instead of alphabetical.\n" +"This does *not* change the file;\n" +"instead, it sends the sorted result to the screen:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:348 +msgid "" +"~~~\n" +"$ sort -n lengths.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:353 +msgid "" +"~~~\n" +" 9 methane.pdb\n" +" 12 ethane.pdb\n" +" 15 propane.pdb\n" +" 20 cubane.pdb\n" +" 21 pentane.pdb\n" +" 30 octane.pdb\n" +"107 total\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:364 +msgid "" +"We can put the sorted list of lines in another temporary file called `sorted-" +"lengths.txt`\n" +"by putting `> sorted-lengths.txt` after the command,\n" +"just as we used `> lengths.txt` to put the output of `wc` into `lengths." +"txt`.\n" +"Once we've done that,\n" +"we can run another command called `head` to get the first few lines in " +"`sorted-lengths.txt`:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:370 +msgid "" +"~~~\n" +"$ sort -n lengths.txt > sorted-lengths.txt\n" +"$ head -n 1 sorted-lengths.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:376 +#: shell-novice/_episodes/04-pipefilter.md:415 +msgid "" +"~~~\n" +" 9 methane.pdb\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:381 +msgid "" +"Using `-n 1` with `head` tells it that\n" +"we only want the first line of the file;\n" +"`-n 20` would get the first 20,\n" +"and so on.\n" +"Since `sorted-lengths.txt` contains the lengths of our files ordered from " +"least to greatest,\n" +"the output of `head` must be the file with the fewest lines." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:388 +msgid "> ## Redirecting to the same file" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:389 +msgid "" +">\n" +"> It's a very bad idea to try redirecting\n" +"> the output of a command that operates on a file\n" +"> to the same file. For example:\n" +">\n" +"> ~~~\n" +"> $ sort -n lengths.txt > lengths.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Doing something like this may give you\n" +"> incorrect results and/or delete\n" +"> the contents of `lengths.txt`." +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:404 +msgid "" +"If you think this is confusing,\n" +"you're in good company:\n" +"even once you understand what `wc`, `sort`, and `head` do,\n" +"all those intermediate files make it hard to follow what's going on.\n" +"We can make it easier to understand by running `sort` and `head` together:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:410 +msgid "" +"~~~\n" +"$ sort -n lengths.txt | head -n 1\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:420 +msgid "" +"The vertical bar, `|`, between the two commands is called a **pipe**.\n" +"It tells the shell that we want to use\n" +"the output of the command on the left\n" +"as the input to the command on the right.\n" +"The computer might create a temporary file if it needs to,\n" +"or copy data from one program to the other in memory,\n" +"or something else entirely;\n" +"we don't have to know or care." +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:429 +msgid "" +"Nothing prevents us from chaining pipes consecutively.\n" +"That is, we can for example send the output of `wc` directly to `sort`,\n" +"and then the resulting output to `head`.\n" +"Thus we first use a pipe to send the output of `wc` to `sort`:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:434 +#: shell-novice/_episodes/06-script.md:223 +msgid "" +"~~~\n" +"$ wc -l *.pdb | sort -n\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:439 +msgid "" +"~~~\n" +" 9 methane.pdb\n" +" 12 ethane.pdb\n" +" 15 propane.pdb\n" +" 20 cubane.pdb\n" +" 21 pentane.pdb\n" +" 30 octane.pdb\n" +" 107 total\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:450 +msgid "" +"And now we send the output of this pipe, through another pipe, to `head`, so " +"that the full pipeline becomes:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:452 +msgid "" +"~~~\n" +"$ wc -l *.pdb | sort -n | head -n 1\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:457 +msgid "" +"~~~\n" +" 9 methane.pdb\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:462 +msgid "" +"This is exactly like a mathematician nesting functions like *log(3x)*\n" +"and saying \"the log of three times *x*\".\n" +"In our case,\n" +"the calculation is \"head of sort of line count of `*.pdb`\"." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:467 +msgid "> ## Piping Commands Together" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:468 +msgid "" +">\n" +"> In our current directory, we want to find the 3 files which have the least " +"number of\n" +"> lines. Which command listed below would work?\n" +">\n" +"> 1. `wc -l * > sort -n > head -n 3`\n" +"> 2. `wc -l * | sort -n | head -n 1-3`\n" +"> 3. `wc -l * | head -n 3 | sort -n`\n" +"> 4. `wc -l * | sort -n | head -n 3`\n" +">\n" +"> > ## Solution\n" +"> > Option 4 is the solution.\n" +"> > The pipe character `|` is used to feed the standard output from one " +"process to\n" +"> > the standard input of another.\n" +"> > `>` is used to redirect standard output to a file.\n" +"> > Try it in the `data-shell/molecules` directory!" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:486 +msgid "" +"Here's what actually happens behind the scenes when we create a pipe.\n" +"When a computer runs a program --- any program --- it creates a **process**\n" +"in memory to hold the program's software and its current state.\n" +"Every process has an input channel called **standard input**.\n" +"(By this point, you may be surprised that the name is so memorable, but " +"don't worry:\n" +"most Unix programmers call it \"stdin\").\n" +"Every process also has a default output channel called **standard output**\n" +"(or \"stdout\"). A second output channel called **standard error** (stderr) " +"also\n" +"exists. This channel is typically used for error or diagnostic messages, and " +"it\n" +"allows a user to pipe the output of one program into another while still " +"receiving \n" +"error messages in the terminal. " +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:498 +msgid "" +"The shell is actually just another program.\n" +"Under normal circumstances,\n" +"whatever we type on the keyboard is sent to the shell on its standard " +"input,\n" +"and whatever it produces on standard output is displayed on our screen.\n" +"When we tell the shell to run a program,\n" +"it creates a new process\n" +"and temporarily sends whatever we type on our keyboard to that process's " +"standard input,\n" +"and whatever the process sends to standard output to the screen." +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:507 +msgid "" +"Here's what happens when we run `wc -l *.pdb > lengths.txt`.\n" +"The shell starts by telling the computer to create a new process to run the " +"`wc` program.\n" +"Since we've provided some filenames as arguments,\n" +"`wc` reads from them instead of from standard input.\n" +"And since we've used `>` to redirect output to a file,\n" +"the shell connects the process's standard output to that file." +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:514 +msgid "" +"If we run `wc -l *.pdb | sort -n` instead,\n" +"the shell creates two processes\n" +"(one for each process in the pipe)\n" +"so that `wc` and `sort` run simultaneously.\n" +"The standard output of `wc` is fed directly to the standard input of " +"`sort`;\n" +"since there's no redirection with `>`,\n" +"`sort`'s output goes to the screen.\n" +"And if we run `wc -l *.pdb | sort -n | head -n 1`,\n" +"we get three processes with data flowing from the files,\n" +"through `wc` to `sort`,\n" +"and from `sort` through `head` to the screen." +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:526 +msgid "![Redirects and Pipes](../fig/redirects-and-pipes.png)" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:528 +msgid "" +"This simple idea is why Unix has been so successful.\n" +"Instead of creating enormous programs that try to do many different things,\n" +"Unix programmers focus on creating lots of simple tools that each do one job " +"well,\n" +"and that work well with each other.\n" +"This programming model is called \"pipes and filters\".\n" +"We've already seen pipes;\n" +"a **filter** is a program like `wc` or `sort`\n" +"that transforms a stream of input into a stream of output.\n" +"Almost all of the standard Unix tools can work this way:\n" +"unless told to do otherwise,\n" +"they read from standard input,\n" +"do something with what they've read,\n" +"and write to standard output." +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:542 +msgid "" +"The key is that any program that reads lines of text from standard input\n" +"and writes lines of text to standard output\n" +"can be combined with every other program that behaves this way as well.\n" +"You can *and should* write your programs this way\n" +"so that you and other people can put those programs into pipes to multiply " +"their power." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:548 +msgid "> ## Redirecting Input" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:549 +msgid "" +">\n" +"> As well as using `>` to redirect a program's output, we can use `<` to\n" +"> redirect its input, i.e., to read from a file instead of from standard\n" +"> input. For example, instead of writing `wc ammonia.pdb`, we could write\n" +"> `wc < ammonia.pdb`. In the first case, `wc` gets a command line\n" +"> argument telling it what file to open. In the second, `wc` doesn't have\n" +"> any command line arguments, so it reads from standard input, but we\n" +"> have told the shell to send the contents of `ammonia.pdb` to `wc`'s\n" +"> standard input." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:560 +msgid "> ## What Does `<` Mean?" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:561 +msgid "" +">\n" +"> Change directory to `data-shell` (the top level of our downloaded example " +"data).\n" +">\n" +"> What is the difference between:\n" +">\n" +"> ~~~\n" +"> $ wc -l notes.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> and:\n" +">\n" +"> ~~~\n" +"> $ wc -l < notes.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> > ## Solution\n" +"> > `<` is used to redirect input to a command. \n" +"> >\n" +"> > In both examples, the shell returns the number of lines from the input " +"to\n" +"> > the `wc` command.\n" +"> > In the first example, the input is the file `notes.txt` and the file " +"name is\n" +"> > given in the output from the `wc` command.\n" +"> > In the second example, the contents of the file `notes.txt` are " +"redirected to\n" +"> > standard input.\n" +"> > It is as if we have entered the contents of the file by typing at the " +"prompt.\n" +"> > Hence the file name is not given in the output - just the number of " +"lines.\n" +"> > Try this for yourself:\n" +"> >\n" +"> > ```\n" +"> > $ wc -l\n" +"> > this\n" +"> > is\n" +"> > a test\n" +"> > Ctrl-D # This lets the shell know you have finished typing the input\n" +"> > ```\n" +"> > {: .language-bash}\n" +"> >\n" +"> > ```\n" +"> > 3\n" +"> > ```\n" +"> > {: .output}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:607 +msgid "> ## Why Does `uniq` Only Remove Adjacent Duplicates?" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:608 +msgid "" +">\n" +"> The command `uniq` removes adjacent duplicated lines from its input.\n" +"> For example, the file `data-shell/data/salmon.txt` contains:\n" +">\n" +"> ~~~\n" +"> coho\n" +"> coho\n" +"> steelhead\n" +"> coho\n" +"> steelhead\n" +"> steelhead\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:621 +msgid "" +">\n" +"> Running the command `uniq salmon.txt` from the `data-shell/data` directory " +"produces:\n" +">\n" +"> ~~~\n" +"> coho\n" +"> steelhead\n" +"> coho\n" +"> steelhead\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:631 +msgid "" +">\n" +"> Why do you think `uniq` only removes *adjacent* duplicated lines?\n" +"> (Hint: think about very large data sets.) What other command could\n" +"> you combine with it in a pipe to remove all duplicated lines?\n" +">\n" +"> > ## Solution\n" +"> > ```\n" +"> > $ sort salmon.txt | uniq\n" +"> > ```\n" +"> > {: .language-bash}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:644 +msgid "> ## Pipe Reading Comprehension" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:645 +msgid "" +">\n" +"> A file called `animals.txt` (in the `data-shell/data` folder) contains the " +"following data:\n" +">\n" +"> ~~~\n" +"> 2012-11-05,deer\n" +"> 2012-11-05,rabbit\n" +"> 2012-11-05,raccoon\n" +"> 2012-11-06,rabbit\n" +"> 2012-11-06,deer\n" +"> 2012-11-06,fox\n" +"> 2012-11-07,rabbit\n" +"> 2012-11-07,bear\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:659 +msgid "" +">\n" +"> What text passes through each of the pipes and the final redirect in the " +"pipeline below?\n" +">\n" +"> ~~~\n" +"> $ cat animals.txt | head -n 5 | tail -n 3 | sort -r > final.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> Hint: build the pipeline up one command at a time to test your " +"understanding" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:669 +msgid "> ## Pipe Construction" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:670 +msgid "" +">\n" +"> For the file `animals.txt` from the previous exercise, the command:\n" +">\n" +"> ~~~\n" +"> $ cut -d , -f 2 animals.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> \n" +"> uses the -d flag to separate each line by comma, and the -f flag\n" +"> to print the second field in each line, to give the following output:\n" +">\n" +"> ~~~\n" +"> deer\n" +"> rabbit\n" +"> raccoon\n" +"> rabbit\n" +"> deer\n" +"> fox\n" +"> rabbit\n" +"> bear\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:692 +msgid "" +">\n" +"> What other command(s) could be added to this in a pipeline to find\n" +"> out what animals the file contains (without any duplicates in their\n" +"> names)?\n" +">\n" +"> > ## Solution\n" +"> > ```\n" +"> > $ cut -d , -f 2 animals.txt | sort | uniq\n" +"> > ```\n" +"> > {: .language-bash}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:705 +msgid "> ## Which Pipe?" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:706 +msgid "" +">\n" +"> The file `animals.txt` contains 586 lines of data formatted as follows:\n" +">\n" +"> ~~~\n" +"> 2012-11-05,deer\n" +"> 2012-11-05,rabbit\n" +"> 2012-11-05,raccoon\n" +"> 2012-11-06,rabbit\n" +"> ...\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:717 +msgid "" +">\n" +"> Assuming your current directory is `data-shell/data/`,\n" +"> what command would you use to produce a table that shows\n" +"> the total count of each type of animal in the file?\n" +">\n" +"> 1. `grep {deer, rabbit, raccoon, deer, fox, bear} animals.txt | wc -l`\n" +"> 2. `sort animals.txt | uniq -c`\n" +"> 3. `sort -t, -k2,2 animals.txt | uniq -c`\n" +"> 4. `cut -d, -f 2 animals.txt | uniq -c`\n" +"> 5. `cut -d, -f 2 animals.txt | sort | uniq -c`\n" +"> 6. `cut -d, -f 2 animals.txt | sort | uniq -c | wc -l`\n" +">\n" +"> > ## Solution\n" +"> > Option 5. is the correct answer.\n" +"> > If you have difficulty understanding why, try running the commands, or " +"sub-sections of\n" +"> > the pipelines (make sure you are in the `data-shell/data` directory)." +msgstr "" + +# header +#: shell-novice/_episodes/04-pipefilter.md:736 +msgid "## Nelle's Pipeline: Checking Files" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:738 +msgid "" +"Nelle has run her samples through the assay machines\n" +"and created 17 files in the `north-pacific-gyre/2012-07-03` directory " +"described earlier.\n" +"As a quick sanity check, starting from her home directory, Nelle types:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:742 +msgid "" +"~~~\n" +"$ cd north-pacific-gyre/2012-07-03\n" +"$ wc -l *.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:748 +msgid "The output is 18 lines that look like this:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:750 +msgid "" +"~~~\n" +"300 NENE01729A.txt\n" +"300 NENE01729B.txt\n" +"300 NENE01736A.txt\n" +"300 NENE01751A.txt\n" +"300 NENE01751B.txt\n" +"300 NENE01812A.txt\n" +"... ...\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:761 +msgid "Now she types this:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:763 +msgid "" +"~~~\n" +"$ wc -l *.txt | sort -n | head -n 5\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:768 +msgid "" +"~~~\n" +" 240 NENE02018B.txt\n" +" 300 NENE01729A.txt\n" +" 300 NENE01729B.txt\n" +" 300 NENE01736A.txt\n" +" 300 NENE01751A.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:777 +msgid "" +"Whoops: one of the files is 60 lines shorter than the others.\n" +"When she goes back and checks it,\n" +"she sees that she did that assay at 8:00 on a Monday morning --- someone\n" +"was probably in using the machine on the weekend,\n" +"and she forgot to reset it.\n" +"Before re-running that sample,\n" +"she checks to see if any files have too much data:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:785 +msgid "" +"~~~\n" +"$ wc -l *.txt | sort -n | tail -n 5\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:790 +msgid "" +"~~~\n" +" 300 NENE02040B.txt\n" +" 300 NENE02040Z.txt\n" +" 300 NENE02043A.txt\n" +" 300 NENE02043B.txt\n" +"5040 total\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:799 +msgid "" +"Those numbers look good --- but what's that 'Z' doing there in the third-to-" +"last line?\n" +"All of her samples should be marked 'A' or 'B';\n" +"by convention,\n" +"her lab uses 'Z' to indicate samples with missing information.\n" +"To find others like it, she does this:" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:805 +msgid "" +"~~~\n" +"$ ls *Z.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/04-pipefilter.md:810 +msgid "" +"~~~\n" +"NENE01971Z.txt NENE02040Z.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:815 +msgid "" +"Sure enough,\n" +"when she checks the log on her laptop,\n" +"there's no depth recorded for either of those samples.\n" +"Since it's too late to get the information any other way,\n" +"she must exclude those two files from her analysis.\n" +"She could just delete them using `rm`,\n" +"but there are actually some analyses she might do later where depth doesn't " +"matter,\n" +"so instead, she'll just be careful later on to select files using the " +"wildcard expression `*[AB].txt`.\n" +"As always,\n" +"the `*` matches any number of characters;\n" +"the expression `[AB]` matches either an 'A' or a 'B',\n" +"so this matches all the valid data files she has." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:828 +msgid "> ## Wildcard Expressions" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:829 +msgid "" +">\n" +"> Wildcard expressions can be very complex, but you can sometimes write\n" +"> them in ways that only use simple syntax, at the expense of being a bit\n" +"> more verbose. \n" +"> Consider the directory `data-shell/north-pacific-gyre/2012-07-03` :\n" +"> the wildcard expression `*[AB].txt`\n" +"> matches all files ending in `A.txt` or `B.txt`. Imagine you forgot about\n" +"> this.\n" +">\n" +"> 1. Can you match the same set of files with basic wildcard expressions\n" +"> that do not use the `[]` syntax? *Hint*: You may need more than one\n" +"> expression.\n" +">\n" +"> 2. The expression that you found and the expression from the lesson match " +"the\n" +"> same set of files in this example. What is the small difference " +"between the\n" +"> outputs?\n" +">\n" +"> 3. Under what circumstances would your new expression produce an error " +"message\n" +"> where the original one would not?\n" +">\n" +"> > ## Solution\n" +"> > 1. \n" +"> >\n" +"> > \t```\n" +"> > \t$ ls *A.txt\n" +"> > \t$ ls *B.txt\n" +"> > \t```\n" +"> >\t{: .language-bash}\n" +"> > 2. The output from the new commands is separated because there are two " +"commands.\n" +"> > 3. When there are no files ending in `A.txt`, or there are no files " +"ending in\n" +"> > `B.txt`." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/04-pipefilter.md:863 +msgid "> ## Removing Unneeded Files" +msgstr "" + +#: shell-novice/_episodes/04-pipefilter.md:864 +msgid "" +">\n" +"> Suppose you want to delete your processed data files, and only keep\n" +"> your raw files and processing script to save storage.\n" +"> The raw files end in `.dat` and the processed files end in `.txt`.\n" +"> Which of the following would remove all the processed data files,\n" +"> and *only* the processed data files?\n" +">\n" +"> 1. `rm ?.txt`\n" +"> 2. `rm *.txt`\n" +"> 3. `rm * .txt`\n" +"> 4. `rm *.*`\n" +">\n" +"> > ## Solution\n" +"> > 1. This would remove `.txt` files with one-character names\n" +"> > 2. This is correct answer\n" +"> > 3. The shell would expand `*` to match everything in the current " +"directory,\n" +"> > so the command would try to remove all matched files and an additional\n" +"> > file called `.txt`\n" +"> > 4. The shell would expand `*.*` to match all files with any extension,\n" +"> > so this command would delete all files" +msgstr "" + +# Front Matter +#: shell-novice/_episodes/05-loop.md:1 +msgid "" +"---\n" +"title: \"Loops\"\n" +"teaching: 40\n" +"exercises: 10\n" +"questions:\n" +"- \"How can I perform the same actions on many different files?\"\n" +"objectives:\n" +"- \"Write a loop that applies one or more commands separately to each file " +"in a set of files.\"\n" +"- \"Trace the values taken on by a loop variable during execution of the " +"loop.\"\n" +"- \"Explain the difference between a variable's name and its value.\"\n" +"- \"Explain why spaces and some punctuation characters shouldn't be used in " +"file names.\"\n" +"- \"Demonstrate how to see what commands have recently been executed.\"\n" +"- \"Re-run recently executed commands without retyping them.\"\n" +"keypoints:\n" +"- \"A `for` loop repeats commands once for every thing in a list.\"\n" +"- \"Every `for` loop needs a variable to refer to the thing it is currently " +"operating on.\"\n" +"- \"Use `$name` to expand a variable (i.e., get its value). `${name}` can " +"also be used.\"\n" +"- \"Do not use spaces, quotes, or wildcard characters such as '*' or '?' in " +"filenames, as it complicates variable expansion.\"\n" +"- \"Give files consistent names that are easy to match with wildcard " +"patterns to make it easy to select them for looping.\"\n" +"- \"Use the up-arrow key to scroll up through previous commands to edit and " +"repeat them.\"\n" +"- \"Use `Ctrl-R` to search through the previously entered commands.\"\n" +"- \"Use `history` to display recent commands, and `!number` to repeat a " +"command by number.\"\n" +"---" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:25 +msgid "" +"**Loops** are key to productivity improvements through automation as they " +"allow us to execute\n" +"commands repetitively. Similar to wildcards and tab completion, using loops " +"also reduces the\n" +"amount of typing (and typing mistakes).\n" +"Suppose we have several hundred genome data files named `basilisk.dat`, " +"`unicorn.dat`, and so on.\n" +"In this example,\n" +"we'll use the `creatures` directory which only has two example files,\n" +"but the principles can be applied to many many more files at once.\n" +"We would like to modify these files, but also save a version of the original " +"files, naming the copies\n" +"`original-basilisk.dat` and `original-unicorn.dat`.\n" +"We can't use:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:36 +msgid "" +"~~~\n" +"$ cp *.dat original-*.dat\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:41 +msgid "because that would expand to:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:43 +msgid "" +"~~~\n" +"$ cp basilisk.dat unicorn.dat original-*.dat\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:48 +msgid "This wouldn't back up our files, instead we get an error:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:50 +msgid "" +"~~~\n" +"cp: target `original-*.dat' is not a directory\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:55 +msgid "" +"This problem arises when `cp` receives more than two inputs. When this " +"happens, it\n" +"expects the last input to be a directory where it can copy all the files it " +"was passed.\n" +"Since there is no directory named `original-*.dat` in the `creatures` " +"directory we get an\n" +"error." +msgstr "" + +#: shell-novice/_episodes/05-loop.md:60 +msgid "" +"Instead, we can use a **loop**\n" +"to do some operation once for each thing in a list.\n" +"Here's a simple example that displays the first three lines of each file in " +"turn:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:64 +msgid "" +"~~~\n" +"$ for filename in basilisk.dat unicorn.dat\n" +"> do\n" +"> head -n 3 $filename\t# Indentation within the loop aids legibility\n" +"> done\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:72 +msgid "" +"~~~\n" +"COMMON NAME: basilisk\n" +"CLASSIFICATION: basiliscus vulgaris\n" +"UPDATED: 1745-05-02\n" +"COMMON NAME: unicorn\n" +"CLASSIFICATION: equus monoceros\n" +"UPDATED: 1738-11-24\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:82 +msgid "> ## Indentation of code within a for loop" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:83 +msgid "" +"> Note that it is common practice to indent the line(s) of code within a for " +"loop." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:84 +msgid "" +"> The only purpose is to make the code easier to read -- it is not required " +"for the loop to run." +msgstr "" + +#: shell-novice/_episodes/05-loop.md:87 +msgid "" +"When the shell sees the keyword `for`,\n" +"it knows to repeat a command (or group of commands) once for each item in a " +"list.\n" +"Each time the loop runs (called an iteration), an item in the list is " +"assigned in sequence to\n" +"the **variable**, and the commands inside the loop are executed, before " +"moving on to \n" +"the next item in the list.\n" +"Inside the loop,\n" +"we call for the variable's value by putting `$` in front of it.\n" +"The `$` tells the shell interpreter to treat\n" +"the **variable** as a variable name and substitute its value in its place,\n" +"rather than treat it as text or an external command. " +msgstr "" + +#: shell-novice/_episodes/05-loop.md:98 +msgid "" +"In this example, the list is two filenames: `basilisk.dat` and `unicorn." +"dat`.\n" +"Each time the loop iterates, it will assign a file name to the variable " +"`filename`\n" +"and run the `head` command.\n" +"The first time through the loop,\n" +"`$filename` is `basilisk.dat`. \n" +"The interpreter runs the command `head` on `basilisk.dat`, \n" +"and the prints the \n" +"first three lines of `basilisk.dat`.\n" +"For the second iteration, `$filename` becomes \n" +"`unicorn.dat`. This time, the shell runs `head` on `unicorn.dat`\n" +"and prints the first three lines of `unicorn.dat`. \n" +"Since the list was only two items, the shell exits the `for` loop." +msgstr "" + +#: shell-novice/_episodes/05-loop.md:111 +msgid "" +"When using variables it is also\n" +"possible to put the names into curly braces to clearly delimit the variable\n" +"name: `$filename` is equivalent to `${filename}`, but is different from\n" +"`${file}name`. You may find this notation in other people's programs." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:116 +msgid "> ## Variables in Loops" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:117 +msgid "" +">\n" +"> This exercise refers to the `data-shell/molecules` directory.\n" +"> `ls` gives the following output:\n" +">\n" +"> ~~~\n" +"> cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:125 +msgid "" +">\n" +"> What is the output of the following code?\n" +">\n" +"> ~~~\n" +"> for datafile in *.pdb\n" +"> do\n" +"> ls *.pdb\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Now, what is the output of the following code?\n" +">\n" +"> ~~~\n" +"> for datafile in *.pdb\n" +"> do\n" +">\tls $datafile\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Why do these two loops give different outputs?\n" +">\n" +"> > ## Solution\n" +"> > The first code block gives the same output on each iteration through\n" +"> > the loop.\n" +"> > Bash expands the wildcard `*.pdb` within the loop body (as well as\n" +"> > before the loop starts) to match all files ending in `.pdb`\n" +"> > and then lists them using `ls`.\n" +"> > The expanded loop would look like this:\n" +"> > ```\n" +"> > for datafile in cubane.pdb ethane.pdb methane.pdb octane.pdb pentane." +"pdb propane.pdb\n" +"> > do\n" +"> >\tls cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb " +"propane.pdb\n" +"> > done\n" +"> > ```\n" +"> > {: .language-bash}\n" +"> >\n" +"> > ```\n" +"> > cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane." +"pdb\n" +"> > cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane." +"pdb\n" +"> > cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane." +"pdb\n" +"> > cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane." +"pdb\n" +"> > cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane." +"pdb\n" +"> > cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane." +"pdb\n" +"> > ```\n" +"> > {: .output}\n" +"> >\n" +"> > The second code block lists a different file on each loop iteration.\n" +"> > The value of the `datafile` variable is evaluated using `$datafile`,\n" +"> > and then listed using `ls`.\n" +"> >\n" +"> > ```\n" +"> > cubane.pdb\n" +"> > ethane.pdb\n" +"> > methane.pdb\n" +"> > octane.pdb\n" +"> > pentane.pdb\n" +"> > propane.pdb\n" +"> > ```\n" +"> > {: .output}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:189 +msgid "> ## Follow the Prompt" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:190 +msgid "" +">\n" +"> The shell prompt changes from `$` to `>` and back again as we were\n" +"> typing in our loop. The second prompt, `>`, is different to remind\n" +"> us that we haven't finished typing a complete command yet. A semicolon, `;" +"`,\n" +"> can be used to separate two commands written on a single line." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:197 +msgid "> ## Same Symbols, Different Meanings" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:198 +msgid "" +">\n" +"> Here we see `>` being used a shell prompt, whereas `>` is also\n" +"> used to redirect output.\n" +"> Similarly, `$` is used as a shell prompt, but, as we saw earlier,\n" +"> it is also used to ask the shell to get the value of a variable.\n" +">\n" +"> If the *shell* prints `>` or `$` then it expects you to type something,\n" +"> and the symbol is a prompt.\n" +">\n" +"> If *you* type `>` or `$` yourself, it is an instruction from you that\n" +"> the shell to redirect output or get the value of a variable." +msgstr "" + +#: shell-novice/_episodes/05-loop.md:211 +msgid "" +"Returning to our example in the `data-shell/creatures` directory,\n" +"we have called the variable in this loop `filename`\n" +"in order to make its purpose clearer to human readers.\n" +"The shell itself doesn't care what the variable is called;\n" +"if we wrote this loop as:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:217 +msgid "" +"~~~\n" +"for x in basilisk.dat unicorn.dat\n" +"do\n" +" head -n 3 $x\n" +"done\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:225 +msgid "or:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:227 +msgid "" +"~~~\n" +"for temperature in basilisk.dat unicorn.dat\n" +"do\n" +" head -n 3 $temperature\n" +"done\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:235 +msgid "" +"it would work exactly the same way.\n" +"*Don't do this.*\n" +"Programs are only useful if people can understand them,\n" +"so meaningless names (like `x`) or misleading names (like `temperature`)\n" +"increase the odds that the program won't do what its readers think it does." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:241 +msgid "> ## Limiting Sets of Files" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:242 +msgid "" +">\n" +"> What would be the output of running the following loop in the `data-shell/" +"molecules` directory?\n" +">\n" +"> ~~~\n" +"> for filename in c*\n" +"> do\n" +"> ls $filename \n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> 1. No files are listed.\n" +"> 2. All files are listed.\n" +"> 3. Only `cubane.pdb`, `octane.pdb` and `pentane.pdb` are listed.\n" +"> 4. Only `cubane.pdb` is listed.\n" +">\n" +"> > ## Solution\n" +"> > 4 is the correct answer. `*` matches zero or more characters, so any " +"file name starting with \n" +"> > the letter c, followed by zero or more other characters will be matched." +msgstr "" + +#: shell-novice/_episodes/05-loop.md:262 +msgid "" +">\n" +"> How would the output differ from using this command instead?\n" +">\n" +"> ~~~\n" +"> for filename in *c*\n" +"> do\n" +"> ls $filename \n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> 1. The same files would be listed.\n" +"> 2. All the files are listed this time.\n" +"> 3. No files are listed this time.\n" +"> 4. The files `cubane.pdb` and `octane.pdb` will be listed.\n" +"> 5. Only the file `octane.pdb` will be listed.\n" +">\n" +"> > ## Solution\n" +"> > 4 is the correct answer. `*` matches zero or more characters, so a file " +"name with zero or more\n" +"> > characters before a letter c and zero or more characters after the " +"letter c will be matched." +msgstr "" + +#: shell-novice/_episodes/05-loop.md:285 +msgid "" +"Let's continue with our example in the `data-shell/creatures` directory.\n" +"Here's a slightly more complicated loop:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:288 +msgid "" +"~~~\n" +"for filename in *.dat\n" +"do\n" +" echo $filename\n" +" head -n 100 $filename | tail -n 20\n" +"done\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:297 +msgid "" +"The shell starts by expanding `*.dat` to create the list of files it will " +"process.\n" +"The **loop body**\n" +"then executes two commands for each of those files.\n" +"The first, `echo`, just prints its command-line arguments to standard " +"output.\n" +"For example:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:303 +msgid "" +"~~~\n" +"$ echo hello there\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:308 +msgid "prints:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:310 +msgid "" +"~~~\n" +"hello there\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:315 +msgid "" +"In this case,\n" +"since the shell expands `$filename` to be the name of a file,\n" +"`echo $filename` just prints the name of the file.\n" +"Note that we can't write this as:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:320 +msgid "" +"~~~\n" +"for filename in *.dat\n" +"do\n" +" $filename\n" +" head -n 100 $filename | tail -n 20\n" +"done\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:329 +msgid "" +"because then the first time through the loop,\n" +"when `$filename` expanded to `basilisk.dat`, the shell would try to run " +"`basilisk.dat` as a program.\n" +"Finally,\n" +"the `head` and `tail` combination selects lines 81-100\n" +"from whatever file is being processed\n" +"(assuming the file has at least 100 lines)." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:336 +msgid "> ## Spaces in Names" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:337 +msgid "" +">\n" +"> Whitespace is used to separate the elements on the list\n" +"> that we are going to loop over. If on the list we have elements\n" +"> with whitespace we need to quote those elements\n" +"> and our variable when using it.\n" +"> Suppose our data files are named:\n" +">\n" +"> ~~~\n" +"> red dragon.dat\n" +"> purple unicorn.dat\n" +"> ~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:350 +msgid "> We need to use" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:353 +msgid "> for filename in \"red dragon.dat\" \"purple unicorn.dat\"" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:354 +msgid "> do" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:355 +msgid "> head -n 100 \"$filename\" | tail -n 3" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:356 +msgid "> done" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:359 +msgid "" +">\n" +"> It is simpler just to avoid using whitespaces (or other special " +"characters) in filenames.\n" +">\n" +"> The files above don't exist, so if we run the above code, the `head` " +"command will be unable\n" +"> to find them, however the error message returned will show the name of the " +"files it is\n" +"> expecting:\n" +"> ```\n" +"> head: cannot open ‘red dragon.dat’ for reading: No such file or directory\n" +"> head: cannot open ‘purple unicorn.dat’ for reading: No such file or " +"directory\n" +"> ```" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:370 +msgid "" +"> Try removing the quotes around `$filename` in the loop above to see the " +"effect of the quote" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:371 +msgid "" +"> marks on whitespace. Note that we get a result from the loop command for " +"unicorn.dat when we run this code in the `creatures` directory:" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:372 shell-novice/_episodes/05-loop.md:379 +msgid "> ```" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:373 +msgid "> head: cannot open ‘red’ for reading: No such file or directory" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:374 +msgid "> head: cannot open ‘dragon.dat’ for reading: No such file or directory" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:375 +msgid "> head: cannot open ‘purple’ for reading: No such file or directory" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:376 +msgid "> CGGTACCGAA" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:377 +msgid "> AAGGGTCGCG" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:378 +msgid "> CAAGTGTTCC" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:380 +msgid "> {: . output}" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:383 +msgid "" +"Going back to our original file copying problem,\n" +"we can solve it using this loop:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:386 +msgid "" +"~~~\n" +"for filename in *.dat\n" +"do\n" +" cp $filename original-$filename\n" +"done\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:394 +msgid "" +"This loop runs the `cp` command once for each filename.\n" +"The first time,\n" +"when `$filename` expands to `basilisk.dat`,\n" +"the shell executes:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:399 +msgid "" +"~~~\n" +"cp basilisk.dat original-basilisk.dat\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:404 +msgid "The second time, the command is:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:406 +msgid "" +"~~~\n" +"cp unicorn.dat original-unicorn.dat\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:411 +msgid "" +"Since the `cp` command does not normally produce any output, it's hard to " +"check \n" +"that the loop is doing the correct thing. By prefixing the command with " +"`echo` \n" +"it is possible to see each command as it _would_ be executed. The following " +"diagram \n" +"shows what happens when the modified script is executed, and demonstrates " +"how the \n" +"judicious use of `echo` is a good debugging technique." +msgstr "" + +#: shell-novice/_episodes/05-loop.md:417 +msgid "![For Loop in Action](../fig/shell_script_for_loop_flow_chart.svg)" +msgstr "" + +# header +#: shell-novice/_episodes/05-loop.md:419 +msgid "## Nelle's Pipeline: Processing Files" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:421 +msgid "" +"Nelle is now ready to process her data files using `goostats` --- a shell " +"script written by her supervisor.\n" +"This calculates some statistics from a protein sample file, and takes two " +"arguments:" +msgstr "" + +# ordered list +#: shell-novice/_episodes/05-loop.md:424 +msgid "1. an input file (containing the raw data)" +msgstr "" + +# ordered list +#: shell-novice/_episodes/05-loop.md:425 +msgid "2. an output file (to store the calculated statistics)" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:427 +msgid "" +"Since she's still learning how to use the shell,\n" +"she decides to build up the required commands in stages.\n" +"Her first step is to make sure that she can select the right input files --- " +"remember,\n" +"these are ones whose names end in 'A' or 'B', rather than 'Z'. Starting from " +"her home directory, Nelle types:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:432 +msgid "" +"~~~\n" +"$ cd north-pacific-gyre/2012-07-03\n" +"$ for datafile in NENE*[AB].txt\n" +"> do\n" +"> echo $datafile\n" +"> done\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:441 +msgid "" +"~~~\n" +"NENE01729A.txt\n" +"NENE01729B.txt\n" +"NENE01736A.txt\n" +"...\n" +"NENE02043A.txt\n" +"NENE02043B.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:451 +msgid "" +"Her next step is to decide\n" +"what to call the files that the `goostats` analysis program will create.\n" +"Prefixing each input file's name with \"stats\" seems simple,\n" +"so she modifies her loop to do that:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:456 +msgid "" +"~~~\n" +"$ for datafile in NENE*[AB].txt\n" +"> do\n" +"> echo $datafile stats-$datafile\n" +"> done\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:464 +msgid "" +"~~~\n" +"NENE01729A.txt stats-NENE01729A.txt\n" +"NENE01729B.txt stats-NENE01729B.txt\n" +"NENE01736A.txt stats-NENE01736A.txt\n" +"...\n" +"NENE02043A.txt stats-NENE02043A.txt\n" +"NENE02043B.txt stats-NENE02043B.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:474 +msgid "" +"She hasn't actually run `goostats` yet,\n" +"but now she's sure she can select the right files and generate the right " +"output filenames." +msgstr "" + +#: shell-novice/_episodes/05-loop.md:477 +msgid "" +"Typing in commands over and over again is becoming tedious,\n" +"though,\n" +"and Nelle is worried about making mistakes,\n" +"so instead of re-entering her loop,\n" +"she presses the up arrow.\n" +"In response,\n" +"the shell redisplays the whole loop on one line\n" +"(using semi-colons to separate the pieces):" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:486 +msgid "" +"~~~\n" +"$ for datafile in NENE*[AB].txt; do echo $datafile stats-$datafile; done\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:491 +msgid "" +"Using the left arrow key,\n" +"Nelle backs up and changes the command `echo` to `bash goostats`:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:494 +msgid "" +"~~~\n" +"$ for datafile in NENE*[AB].txt; do bash goostats $datafile stats-$datafile; " +"done\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:499 +msgid "" +"When she presses Enter,\n" +"the shell runs the modified command.\n" +"However, nothing appears to happen --- there is no output.\n" +"After a moment, Nelle realizes that since her script doesn't print anything " +"to the screen any longer,\n" +"she has no idea whether it is running, much less how quickly.\n" +"She kills the running command by typing `Ctrl-C`,\n" +"uses up-arrow to repeat the command,\n" +"and edits it to read:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:508 +msgid "" +"~~~\n" +"$ for datafile in NENE*[AB].txt; do echo $datafile; bash goostats $datafile " +"stats-$datafile; done\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:513 +msgid "> ## Beginning and End" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:514 +msgid "" +">\n" +"> We can move to the beginning of a line in the shell by typing `Ctrl-a`\n" +"> and to the end using `Ctrl-e`." +msgstr "" + +#: shell-novice/_episodes/05-loop.md:519 +msgid "" +"When she runs her program now,\n" +"it produces one line of output every five seconds or so:" +msgstr "" + +# code block +#: shell-novice/_episodes/05-loop.md:522 +msgid "" +"~~~\n" +"NENE01729A.txt\n" +"NENE01729B.txt\n" +"NENE01736A.txt\n" +"...\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:530 +msgid "" +"1518 times 5 seconds,\n" +"divided by 60,\n" +"tells her that her script will take about two hours to run.\n" +"As a final check,\n" +"she opens another terminal window,\n" +"goes into `north-pacific-gyre/2012-07-03`,\n" +"and uses `cat stats-NENE01729B.txt`\n" +"to examine one of the output files.\n" +"It looks good,\n" +"so she decides to get some coffee and catch up on her reading." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:541 +msgid "> ## Those Who Know History Can Choose to Repeat It" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:542 +msgid "" +">\n" +"> Another way to repeat previous work is to use the `history` command to\n" +"> get a list of the last few hundred commands that have been executed, and\n" +"> then to use `!123` (where \"123\" is replaced by the command number) to\n" +"> repeat one of those commands. For example, if Nelle types this:\n" +">\n" +"> ~~~\n" +"> $ history | tail -n 5\n" +"> ~~~\n" +"> {: .language-bash}\n" +"> ~~~\n" +"> 456 ls -l NENE0*.txt\n" +"> 457 rm stats-NENE01729B.txt.txt\n" +"> 458 bash goostats NENE01729B.txt stats-NENE01729B.txt\n" +"> 459 ls -l NENE0*.txt\n" +"> 460 history\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:560 +msgid "" +">\n" +"> then she can re-run `goostats` on `NENE01729B.txt` simply by typing\n" +"> `!458`." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:565 +msgid "> ## Other History Commands" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:566 +msgid "" +">\n" +"> There are a number of other shortcut commands for getting at the history.\n" +">\n" +"> - `Ctrl-R` enters a history search mode \"reverse-i-search\" and finds " +"the \n" +"> most recent command in your history that matches the text you enter next.\n" +"> Press `Ctrl-R` one or more additional times to search for earlier " +"matches.\n" +"> - `!!` retrieves the immediately preceding command \n" +"> (you may or may not find this more convenient than using the up-arrow)\n" +"> - `!$` retrieves the last word of the last command.\n" +"> That's useful more often than you might expect: after\n" +"> `bash goostats NENE01729B.txt stats-NENE01729B.txt`, you can type\n" +"> `less !$` to look at the file `stats-NENE01729B.txt`, which is\n" +"> quicker than doing up-arrow and editing the command-line." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:581 +msgid "> ## Saving to a File in a Loop - Part One" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:582 +msgid "" +">\n" +"> In the `data-shell/molecules` directory, what is the effect of this loop?\n" +">\n" +"> ~~~\n" +"> for alkanes in *.pdb\n" +"> do\n" +"> echo $alkanes\n" +"> cat $alkanes > alkanes.pdb\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> 1. Prints `cubane.pdb`, `ethane.pdb`, `methane.pdb`, `octane.pdb`, " +"`pentane.pdb` and `propane.pdb`,\n" +"> and the text from `propane.pdb` will be saved to a file called " +"`alkanes.pdb`.\n" +"> 2. Prints `cubane.pdb`, `ethane.pdb`, and `methane.pdb`, and the text " +"from all three files would be\n" +"> concatenated and saved to a file called `alkanes.pdb`.\n" +"> 3. Prints `cubane.pdb`, `ethane.pdb`, `methane.pdb`, `octane.pdb`, and " +"`pentane.pdb`, and the text\n" +"> from `propane.pdb` will be saved to a file called `alkanes.pdb`.\n" +"> 4. None of the above.\n" +">\n" +"> > ## Solution\n" +"> > 1. The text from each file in turn gets written to the `alkanes.pdb` " +"file.\n" +"> > However, the file gets overwritten on each loop interation, so the final " +"content of `alkanes.pdb`\n" +"> > is the text from the `propane.pdb` file." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:609 +msgid "> ## Saving to a File in a Loop - Part Two" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:610 +msgid "" +">\n" +"> Also in the `data-shell/molecules` directory, what would be the output of " +"the following loop?\n" +">\n" +"> ~~~\n" +"> for datafile in *.pdb\n" +"> do\n" +"> cat $datafile >> all.pdb\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> 1. All of the text from `cubane.pdb`, `ethane.pdb`, `methane.pdb`, " +"`octane.pdb`, and\n" +"> `pentane.pdb` would be concatenated and saved to a file called `all." +"pdb`.\n" +"> 2. The text from `ethane.pdb` will be saved to a file called `all.pdb`.\n" +"> 3. All of the text from `cubane.pdb`, `ethane.pdb`, `methane.pdb`, " +"`octane.pdb`, `pentane.pdb`\n" +"> and `propane.pdb` would be concatenated and saved to a file called " +"`all.pdb`.\n" +"> 4. All of the text from `cubane.pdb`, `ethane.pdb`, `methane.pdb`, " +"`octane.pdb`, `pentane.pdb`\n" +"> and `propane.pdb` would be printed to the screen and saved to a file " +"called `all.pdb`.\n" +">\n" +"> > ## Solution\n" +"> > 3 is the correct answer. `>>` appends to a file, rather than overwriting " +"it with the redirected\n" +"> > output from a command.\n" +"> > Given the output from the `cat` command has been redirected, nothing is " +"printed to the screen." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:636 +msgid "> ## Doing a Dry Run" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:637 +msgid "" +">\n" +"> A loop is a way to do many things at once --- or to make many mistakes at\n" +"> once if it does the wrong thing. One way to check what a loop *would* do\n" +"> is to `echo` the commands it would run instead of actually running them.\n" +"> \n" +"> Suppose we want to preview the commands the following loop will execute\n" +"> without actually running those commands:\n" +">\n" +"> ~~~\n" +"> for file in *.pdb\n" +"> do\n" +"> analyze $file > analyzed-$file\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> What is the difference between the two loops below, and which one would " +"we\n" +"> want to run?\n" +">\n" +"> ~~~\n" +"> # Version 1\n" +"> for file in *.pdb\n" +"> do\n" +"> echo analyze $file > analyzed-$file\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> ~~~\n" +"> # Version 2\n" +"> for file in *.pdb\n" +"> do\n" +"> echo \"analyze $file > analyzed-$file\"\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> > ## Solution\n" +"> > The second version is the one we want to run.\n" +"> > This prints to screen everything enclosed in the quote marks, expanding " +"the\n" +"> > loop variable name because we have prefixed it with a dollar sign.\n" +"> >\n" +"> > The first version redirects the output from the command `echo analyze " +"$file` to\n" +"> > a file, `analyzed-$file`. A series of files is generated: `analyzed-" +"cubane.pdb`,\n" +"> > `analyzed-ethane.pdb` etc.\n" +"> > \n" +"> > Try both versions for yourself to see the output! Be sure to open the \n" +"> > `analyzed-*.pdb` files to view their contents." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/05-loop.md:688 +msgid "> ## Nested Loops" +msgstr "" + +#: shell-novice/_episodes/05-loop.md:689 +msgid "" +">\n" +"> Suppose we want to set up up a directory structure to organize\n" +"> some experiments measuring reaction rate constants with different " +"compounds\n" +"> *and* different temperatures. What would be the\n" +"> result of the following code:\n" +">\n" +"> ~~~\n" +"> for species in cubane ethane methane\n" +"> do\n" +"> for temperature in 25 30 37 40\n" +"> do\n" +"> mkdir $species-$temperature\n" +"> done\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> > ## Solution\n" +"> > We have a nested loop, i.e. contained within another loop, so for each " +"species\n" +"> > in the outer loop, the inner loop (the nested loop) iterates over the " +"list of\n" +"> > temperatures, and creates a new directory for each combination.\n" +"> >\n" +"> > Try running the code for yourself to see which directories are created!" +msgstr "" + +# Front Matter +#: shell-novice/_episodes/06-script.md:1 +msgid "" +"---\n" +"title: \"Shell Scripts\"\n" +"teaching: 30\n" +"exercises: 15\n" +"questions:\n" +"- \"How can I save and re-use commands?\"\n" +"objectives:\n" +"- \"Write a shell script that runs a command or series of commands for a " +"fixed set of files.\"\n" +"- \"Run a shell script from the command line.\"\n" +"- \"Write a shell script that operates on a set of files defined by the user " +"on the command line.\"\n" +"- \"Create pipelines that include shell scripts you, and others, have " +"written.\"\n" +"keypoints:\n" +"- \"Save commands in files (usually called shell scripts) for re-use.\"\n" +"- \"`bash filename` runs the commands saved in a file.\"\n" +"- \"`$@` refers to all of a shell script's command-line arguments.\"\n" +"- \"`$1`, `$2`, etc., refer to the first command-line argument, the second " +"command-line argument, etc.\"\n" +"- \"Place variables in quotes if the values might have spaces in them.\"\n" +"- \"Letting users decide what files to process is more flexible and more " +"consistent with built-in Unix commands.\"\n" +"---" +msgstr "" + +#: shell-novice/_episodes/06-script.md:21 +msgid "" +"We are finally ready to see what makes the shell such a powerful programming " +"environment.\n" +"We are going to take the commands we repeat frequently and save them in " +"files\n" +"so that we can re-run all those operations again later by typing a single " +"command.\n" +"For historical reasons,\n" +"a bunch of commands saved in a file is usually called a **shell script**,\n" +"but make no mistake:\n" +"these are actually small programs." +msgstr "" + +#: shell-novice/_episodes/06-script.md:29 +msgid "" +"Let's start by going back to `molecules/` and creating a new file, `middle." +"sh` which will\n" +"become our shell script:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:32 +msgid "" +"~~~\n" +"$ cd molecules\n" +"$ nano middle.sh\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:38 +msgid "" +"The command `nano middle.sh` opens the file `middle.sh` within the text " +"editor \"nano\"\n" +"(which runs within the shell).\n" +"If the file does not exist, it will be created.\n" +"We can use the text editor to directly edit the file -- we'll simply insert " +"the following line:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:43 +msgid "" +"~~~\n" +"head -n 15 octane.pdb | tail -n 5\n" +"~~~" +msgstr "" + +# SC/DC Template label +#: shell-novice/_episodes/06-script.md:46 +#: shell-novice/_episodes/06-script.md:362 +msgid "{: .source}" +msgstr "" + +#: shell-novice/_episodes/06-script.md:48 +msgid "" +"This is a variation on the pipe we constructed earlier:\n" +"it selects lines 11-15 of the file `octane.pdb`.\n" +"Remember, we are *not* running it as a command just yet:\n" +"we are putting the commands in a file." +msgstr "" + +#: shell-novice/_episodes/06-script.md:53 +msgid "" +"Then we save the file (`Ctrl-O` in nano),\n" +" and exit the text editor (`Ctrl-X` in nano).\n" +"Check that the directory `molecules` now contains a file called `middle.sh`." +msgstr "" + +#: shell-novice/_episodes/06-script.md:57 +msgid "" +"Once we have saved the file,\n" +"we can ask the shell to execute the commands it contains.\n" +"Our shell is called `bash`, so we run the following command:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:61 +msgid "" +"~~~\n" +"$ bash middle.sh\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:66 +#: shell-novice/_episodes/06-script.md:117 +msgid "" +"~~~\n" +"ATOM 9 H 1 -4.502 0.681 0.785 1.00 0.00\n" +"ATOM 10 H 1 -5.254 -0.243 -0.537 1.00 0.00\n" +"ATOM 11 H 1 -4.357 1.252 -0.895 1.00 0.00\n" +"ATOM 12 H 1 -3.009 -0.741 -1.467 1.00 0.00\n" +"ATOM 13 H 1 -3.172 -1.337 0.206 1.00 0.00\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:75 +msgid "" +"Sure enough,\n" +"our script's output is exactly what we would get if we ran that pipeline " +"directly." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/06-script.md:78 +msgid "> ## Text vs. Whatever" +msgstr "" + +#: shell-novice/_episodes/06-script.md:79 +msgid "" +">\n" +"> We usually call programs like Microsoft Word or LibreOffice Writer \"text\n" +"> editors\", but we need to be a bit more careful when it comes to\n" +"> programming. By default, Microsoft Word uses `.docx` files to store not\n" +"> only text, but also formatting information about fonts, headings, and so\n" +"> on. This extra information isn't stored as characters, and doesn't mean\n" +"> anything to tools like `head`: they expect input files to contain\n" +"> nothing but the letters, digits, and punctuation on a standard computer\n" +"> keyboard. When editing programs, therefore, you must either use a plain\n" +"> text editor, or be careful to save files as plain text." +msgstr "" + +#: shell-novice/_episodes/06-script.md:91 +msgid "" +"What if we want to select lines from an arbitrary file?\n" +"We could edit `middle.sh` each time to change the filename,\n" +"but that would probably take longer than just retyping the command.\n" +"Instead, let's edit `middle.sh` and make it more versatile:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:96 +#: shell-novice/_episodes/06-script.md:154 +#: shell-novice/_episodes/06-script.md:201 +msgid "" +"~~~\n" +"$ nano middle.sh\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:101 +msgid "" +"Now, within \"nano\", replace the text `octane.pdb` with the special " +"variable called `$1`:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:103 +msgid "" +"~~~\n" +"head -n 15 \"$1\" | tail -n 5\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:108 +msgid "" +"Inside a shell script,\n" +"`$1` means \"the first filename (or other argument) on the command line\".\n" +"We can now run our script like this:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:112 +msgid "" +"~~~\n" +"$ bash middle.sh octane.pdb\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:126 +msgid "or on a different file like this:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:128 +msgid "" +"~~~\n" +"$ bash middle.sh pentane.pdb\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:133 +#: shell-novice/_episodes/06-script.md:171 +msgid "" +"~~~\n" +"ATOM 9 H 1 1.324 0.350 -1.332 1.00 0.00\n" +"ATOM 10 H 1 1.271 1.378 0.122 1.00 0.00\n" +"ATOM 11 H 1 -0.074 -0.384 1.288 1.00 0.00\n" +"ATOM 12 H 1 -0.048 -1.362 -0.205 1.00 0.00\n" +"ATOM 13 H 1 -1.183 0.500 -1.412 1.00 0.00\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/06-script.md:142 +msgid "> ## Double-Quotes Around Arguments" +msgstr "" + +#: shell-novice/_episodes/06-script.md:143 +msgid "" +">\n" +"> For the same reason that we put the loop variable inside double-quotes,\n" +"> in case the filename happens to contain any spaces,\n" +"> we surround `$1` with double-quotes." +msgstr "" + +#: shell-novice/_episodes/06-script.md:149 +msgid "" +"We still need to edit `middle.sh` each time we want to adjust the range of " +"lines,\n" +"though.\n" +"Let's fix that by using the special variables `$2` and `$3` for the\n" +"number of lines to be passed to `head` and `tail` respectively:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:159 +msgid "" +"~~~\n" +"head -n \"$2\" \"$1\" | tail -n \"$3\"\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:164 +msgid "We can now run:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:166 +msgid "" +"~~~\n" +"$ bash middle.sh pentane.pdb 15 5\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:180 +msgid "" +"By changing the arguments to our command we can change our script's\n" +"behaviour:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:183 +msgid "" +"~~~\n" +"$ bash middle.sh pentane.pdb 20 5\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:188 +msgid "" +"~~~\n" +"ATOM 14 H 1 -1.259 1.420 0.112 1.00 0.00\n" +"ATOM 15 H 1 -2.608 -0.407 1.130 1.00 0.00\n" +"ATOM 16 H 1 -2.540 -1.303 -0.404 1.00 0.00\n" +"ATOM 17 H 1 -3.393 0.254 -0.321 1.00 0.00\n" +"TER 18 1\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:197 +msgid "" +"This works,\n" +"but it may take the next person who reads `middle.sh` a moment to figure out " +"what it does.\n" +"We can improve our script by adding some **comments** at the top:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:206 +msgid "" +"~~~\n" +"# Select lines from the middle of a file.\n" +"# Usage: bash middle.sh filename end_line num_lines\n" +"head -n \"$2\" \"$1\" | tail -n \"$3\"\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:213 +msgid "" +"A comment starts with a `#` character and runs to the end of the line.\n" +"The computer ignores comments,\n" +"but they're invaluable for helping people (including your future self) " +"understand and use scripts.\n" +"The only caveat is that each time you modify the script,\n" +"you should check that the comment is still accurate:\n" +"an explanation that sends the reader in the wrong direction is worse than " +"none at all." +msgstr "" + +#: shell-novice/_episodes/06-script.md:220 +msgid "" +"What if we want to process many files in a single pipeline?\n" +"For example, if we want to sort our `.pdb` files by length, we would type:" +msgstr "" + +#: shell-novice/_episodes/06-script.md:228 +msgid "" +"because `wc -l` lists the number of lines in the files\n" +"(recall that `wc` stands for 'word count', adding the `-l` flag means 'count " +"lines' instead)\n" +"and `sort -n` sorts things numerically.\n" +"We could put this in a file,\n" +"but then it would only ever sort a list of `.pdb` files in the current " +"directory.\n" +"If we want to be able to get a sorted list of other kinds of files,\n" +"we need a way to get all those names into the script.\n" +"We can't use `$1`, `$2`, and so on\n" +"because we don't know how many files there are.\n" +"Instead, we use the special variable `$@`,\n" +"which means,\n" +"\"All of the command-line arguments to the shell script.\"\n" +"We also should put `$@` inside double-quotes\n" +"to handle the case of arguments containing spaces\n" +"(`\"$@\"` is equivalent to `\"$1\"` `\"$2\"` ...)\n" +"Here's an example:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:245 +msgid "" +"~~~\n" +"$ nano sorted.sh\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:250 +msgid "" +"~~~\n" +"# Sort filenames by their length.\n" +"# Usage: bash sorted.sh one_or_more_filenames\n" +"wc -l \"$@\" | sort -n\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:257 +msgid "" +"~~~\n" +"$ bash sorted.sh *.pdb ../creatures/*.dat\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:262 +msgid "" +"~~~\n" +"9 methane.pdb\n" +"12 ethane.pdb\n" +"15 propane.pdb\n" +"20 cubane.pdb\n" +"21 pentane.pdb\n" +"30 octane.pdb\n" +"163 ../creatures/basilisk.dat\n" +"163 ../creatures/unicorn.dat\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/06-script.md:274 +msgid "> ## List Unique Species" +msgstr "" + +#: shell-novice/_episodes/06-script.md:275 +msgid "" +">\n" +"> Leah has several hundred data files, each of which is formatted like " +"this:\n" +">\n" +"> ~~~\n" +"> 2013-11-05,deer,5\n" +"> 2013-11-05,rabbit,22\n" +"> 2013-11-05,raccoon,7\n" +"> 2013-11-06,rabbit,19\n" +"> 2013-11-06,deer,2\n" +"> 2013-11-06,fox,1\n" +"> 2013-11-07,rabbit,18\n" +"> 2013-11-07,bear,1\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:289 +msgid "" +">\n" +"> An example of this type of file is given in `data-shell/data/animal-counts/" +"animals.txt`.\n" +"> \n" +"> Write a shell script called `species.sh` that takes any number of\n" +"> filenames as command-line arguments, and uses `cut`, `sort`, and\n" +"> `uniq` to print a list of the unique species appearing in each of\n" +"> those files separately.\n" +">\n" +"> > ## Solution\n" +"> >\n" +"> > ```\n" +"> > # Script to find unique species in csv files where species is the second " +"data field\n" +"> > # This script accepts any number of file names as command line " +"arguments\n" +"> >\n" +"> > # Loop over all files\n" +"> > for file in $@ \n" +"> > do\n" +"> > \techo \"Unique species in $file:\"\n" +"> > \t# Extract species names\n" +"> > \tcut -d , -f 2 $file | sort | uniq\n" +"> > done\n" +"> > ```\n" +"> > {: .source}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/06-script.md:315 +msgid "> ## Why Isn't It Doing Anything?" +msgstr "" + +#: shell-novice/_episodes/06-script.md:316 +msgid "" +">\n" +"> What happens if a script is supposed to process a bunch of files, but we\n" +"> don't give it any filenames? For example, what if we type:\n" +">\n" +"> ~~~\n" +"> $ bash sorted.sh\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> but don't say `*.dat` (or anything else)? In this case, `$@` expands to\n" +"> nothing at all, so the pipeline inside the script is effectively:\n" +">\n" +"> ~~~\n" +"> $ wc -l | sort -n\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Since it doesn't have any filenames, `wc` assumes it is supposed to\n" +"> process standard input, so it just sits there and waits for us to give\n" +"> it some data interactively. From the outside, though, all we see is it\n" +"> sitting there: the script doesn't appear to do anything." +msgstr "" + +#: shell-novice/_episodes/06-script.md:340 +msgid "" +"Suppose we have just run a series of commands that did something useful --- " +"for example,\n" +"that created a graph we'd like to use in a paper.\n" +"We'd like to be able to re-create the graph later if we need to,\n" +"so we want to save the commands in a file.\n" +"Instead of typing them in again\n" +"(and potentially getting them wrong)\n" +"we can do this:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:348 +msgid "" +"~~~\n" +"$ history | tail -n 5 > redo-figure-3.sh\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:353 +msgid "The file `redo-figure-3.sh` now contains:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:355 +msgid "" +"~~~\n" +"297 bash goostats NENE01729B.txt stats-NENE01729B.txt\n" +"298 bash goodiff stats-NENE01729B.txt /data/validated/01729.txt > 01729-" +"differences.txt\n" +"299 cut -d ',' -f 2-3 01729-differences.txt > 01729-time-series.txt\n" +"300 ygraph --format scatter --color bw --borders none 01729-time-series.txt " +"figure-3.png\n" +"301 history | tail -n 5 > redo-figure-3.sh\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:364 +msgid "" +"After a moment's work in an editor to remove the serial numbers on the " +"commands,\n" +"and to remove the final line where we called the `history` command,\n" +"we have a completely accurate record of how we created that figure." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/06-script.md:368 +msgid "> ## Why Record Commands in the History Before Running Them?" +msgstr "" + +#: shell-novice/_episodes/06-script.md:369 +msgid "" +">\n" +"> If you run the command:\n" +">\n" +"> ~~~\n" +"> $ history | tail -n 5 > recent.sh\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> the last command in the file is the `history` command itself, i.e.,\n" +"> the shell has added `history` to the command log before actually\n" +"> running it. In fact, the shell *always* adds commands to the log\n" +"> before running them. Why do you think it does this?\n" +">\n" +"> > ## Solution\n" +"> > If a command causes something to crash or hang, it might be useful\n" +"> > to know what that command was, in order to investigate the problem.\n" +"> > Were the command only be recorded after running it, we would not\n" +"> > have a record of the last command run in the event of a crash." +msgstr "" + +#: shell-novice/_episodes/06-script.md:390 +msgid "" +"In practice, most people develop shell scripts by running commands at the " +"shell prompt a few times\n" +"to make sure they're doing the right thing,\n" +"then saving them in a file for re-use.\n" +"This style of work allows people to recycle\n" +"what they discover about their data and their workflow with one call to " +"`history`\n" +"and a bit of editing to clean up the output\n" +"and save it as a shell script." +msgstr "" + +# header +#: shell-novice/_episodes/06-script.md:398 +msgid "## Nelle's Pipeline: Creating a Script" +msgstr "" + +#: shell-novice/_episodes/06-script.md:400 +msgid "" +"Nelle's supervisor insisted that all her analytics must be reproducible. The " +"easiest way to capture all the steps is in a script.\n" +"She runs the editor and writes the following:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:403 +msgid "" +"~~~\n" +"# Calculate stats for data files.\n" +"for datafile in \"$@\"\n" +"do\n" +" echo $datafile\n" +" bash goostats $datafile stats-$datafile\n" +"done\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:413 +msgid "" +"She saves this in a file called `do-stats.sh`\n" +"so that she can now re-do the first stage of her analysis by typing:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:416 +msgid "" +"~~~\n" +"$ bash do-stats.sh NENE*[AB].txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:421 +msgid "She can also do this:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:423 +msgid "" +"~~~\n" +"$ bash do-stats.sh NENE*[AB].txt | wc -l\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:428 +msgid "" +"so that the output is just the number of files processed\n" +"rather than the names of the files that were processed." +msgstr "" + +#: shell-novice/_episodes/06-script.md:431 +msgid "" +"One thing to note about Nelle's script is that\n" +"it lets the person running it decide what files to process.\n" +"She could have written it as:" +msgstr "" + +# code block +#: shell-novice/_episodes/06-script.md:435 +msgid "" +"~~~\n" +"# Calculate stats for Site A and Site B data files.\n" +"for datafile in NENE*[AB].txt\n" +"do\n" +" echo $datafile\n" +" bash goostats $datafile stats-$datafile\n" +"done\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/06-script.md:445 +msgid "" +"The advantage is that this always selects the right files:\n" +"she doesn't have to remember to exclude the 'Z' files.\n" +"The disadvantage is that it *always* selects just those files --- she can't " +"run it on all files\n" +"(including the 'Z' files),\n" +"or on the 'G' or 'H' files her colleagues in Antarctica are producing,\n" +"without editing the script.\n" +"If she wanted to be more adventurous,\n" +"she could modify her script to check for command-line arguments,\n" +"and use `NENE*[AB].txt` if none were provided.\n" +"Of course, this introduces another tradeoff between flexibility and " +"complexity." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/06-script.md:456 +msgid "> ## Variables in Shell Scripts" +msgstr "" + +#: shell-novice/_episodes/06-script.md:457 +msgid "" +">\n" +"> In the `molecules` directory, imagine you have a shell script called " +"`script.sh` containing the\n" +"> following commands:\n" +">\n" +"> ~~~\n" +"> head -n $2 $1\n" +"> tail -n $3 $1\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> While you are in the `molecules` directory, you type the following " +"command:\n" +">\n" +"> ~~~\n" +"> bash script.sh '*.pdb' 1 1\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Which of the following outputs would you expect to see?\n" +">\n" +"> 1. All of the lines between the first and the last lines of each file " +"ending in `.pdb`\n" +"> in the `molecules` directory\n" +"> 2. The first and the last line of each file ending in `.pdb` in the " +"`molecules` directory\n" +"> 3. The first and the last line of each file in the `molecules` directory\n" +"> 4. An error because of the quotes around `*.pdb`\n" +">\n" +"> > ## Solution\n" +"> > The correct answer is 2. \n" +"> >\n" +"> > The special variables $1, $2 and $3 represent the command line arguments " +"given to the\n" +"> > script, such that the commands run are:\n" +"> >\n" +"> > ```\n" +"> > $ head -n 1 cubane.pdb ethane.pdb octane.pdb pentane.pdb propane.pdb\n" +"> > $ tail -n 1 cubane.pdb ethane.pdb octane.pdb pentane.pdb propane.pdb\n" +"> > ```\n" +"> > {: .language-bash}\n" +"> > The shell does not expand `'*.pdb'` because it is enclosed by quote " +"marks.\n" +"> > As such, the first argument to the script is `'*.pdb'` which gets " +"expanded within the\n" +"> > script by `head` and `tail`." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/06-script.md:499 +msgid "> ## Find the Longest File With a Given Extension" +msgstr "" + +#: shell-novice/_episodes/06-script.md:500 +msgid "" +">\n" +"> Write a shell script called `longest.sh` that takes the name of a\n" +"> directory and a filename extension as its arguments, and prints\n" +"> out the name of the file with the most lines in that directory\n" +"> with that extension. For example:\n" +">\n" +"> ~~~\n" +"> $ bash longest.sh /tmp/data pdb\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> would print the name of the `.pdb` file in `/tmp/data` that has\n" +"> the most lines.\n" +">\n" +"> > ## Solution\n" +"> >\n" +"> > ```\n" +"> > # Shell script which takes two arguments: \n" +"> > # 1. a directory name\n" +"> > # 2. a file extension\n" +"> > # and prints the name of the file in that directory\n" +"> > # with the most lines which matches the file extension.\n" +"> > \n" +"> > wc -l $1/*.$2 | sort -n | tail -n 2 | head -n 1\n" +"> > ```\n" +"> > {: .source}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/06-script.md:529 +msgid "> ## Script Reading Comprehension" +msgstr "" + +#: shell-novice/_episodes/06-script.md:530 +msgid "" +">\n" +"> For this question, consider the `data-shell/molecules` directory once " +"again.\n" +"> This contains a number of `.pdb` files in addition to any other files you\n" +"> may have created.\n" +"> Explain what a script called `example.sh` would do when run as\n" +"> `bash example.sh *.pdb` if it contained the following lines:\n" +">\n" +"> ~~~\n" +"> # Script 1\n" +"> echo *.*\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> ~~~\n" +"> # Script 2\n" +"> for filename in $1 $2 $3\n" +"> do\n" +"> cat $filename\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> ~~~\n" +"> # Script 3\n" +"> echo $@.pdb\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> > ## Solutions\n" +"> > Script 1 would print out a list of all files containing a dot in their " +"name.\n" +"> >\n" +"> > Script 2 would print the contents of the first 3 files matching the file " +"extension.\n" +"> > The shell expands the wildcard before passing the arguments to the " +"`example.sh` script.\n" +"> > \n" +"> > Script 3 would print all the arguments to the script (i.e. all the `." +"pdb` files),\n" +"> > followed by `.pdb`.\n" +"> > ```\n" +"> > cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb." +"pdb\n" +"> > ```\n" +"> > {: .output}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/06-script.md:573 +msgid "> ## Debugging Scripts" +msgstr "" + +#: shell-novice/_episodes/06-script.md:574 +msgid "" +">\n" +"> Suppose you have saved the following script in a file called `do-errors." +"sh`\n" +"> in Nelle's `north-pacific-gyre/2012-07-03` directory:\n" +">\n" +"> ~~~\n" +"> # Calculate stats for data files.\n" +"> for datafile in \"$@\"\n" +"> do\n" +"> echo $datfile\n" +"> bash goostats $datafile stats-$datafile\n" +"> done\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> When you run it:\n" +">\n" +"> ~~~\n" +"> $ bash do-errors.sh NENE*[AB].txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> the output is blank.\n" +"> To figure out why, re-run the script using the `-x` option:\n" +">\n" +"> ~~~\n" +"> bash -x do-errors.sh NENE*[AB].txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> What is the output showing you?\n" +"> Which line is responsible for the error?\n" +">\n" +"> > ## Solution\n" +"> > The `-x` flag causes `bash` to run in debug mode.\n" +"> > This prints out each command as it is run, which will help you to locate " +"errors.\n" +"> > In this example, we can see that `echo` isn't printing anything. We have " +"made a typo\n" +"> > in the loop variable name, and the variable `datfile` doesn't exist, " +"hence returning\n" +"> > an empty string." +msgstr "" + +# Front Matter +#: shell-novice/_episodes/07-find.md:1 +msgid "" +"---\n" +"title: \"Finding Things\"\n" +"teaching: 25\n" +"exercises: 20\n" +"questions:\n" +"- \"How can I find files?\"\n" +"- \"How can I find things in files?\"\n" +"objectives:\n" +"- \"Use `grep` to select lines from text files that match simple patterns." +"\"\n" +"- \"Use `find` to find files whose names match simple patterns.\"\n" +"- \"Use the output of one command as the command-line argument(s) to another " +"command.\"\n" +"- \"Explain what is meant by 'text' and 'binary' files, and why many common " +"tools don't handle the latter well.\"\n" +"keypoints:\n" +"- \"`find` finds files with specific properties that match patterns.\"\n" +"- \"`grep` selects lines in files that match patterns.\"\n" +"- \"`--help` is a flag supported by many bash commands, and programs that " +"can be run from within Bash, to display more information on how to use these " +"commands or programs.\"\n" +"- \"`man command` displays the manual page for a given command.\"\n" +"- \"`$(command)` inserts a command's output in place.\"\n" +"---" +msgstr "" + +#: shell-novice/_episodes/07-find.md:21 +msgid "" +"In the same way that many of us now use \"Google\" as a \n" +"verb meaning \"to find\", Unix programmers often use the \n" +"word \"grep\".\n" +"\"grep\" is a contraction of \"global/regular expression/print\",\n" +"a common sequence of operations in early Unix text editors.\n" +"It is also the name of a very useful command-line program." +msgstr "" + +#: shell-novice/_episodes/07-find.md:28 +msgid "" +"`grep` finds and prints lines in files that match a pattern.\n" +"For our examples,\n" +"we will use a file that contains three haikus taken from a\n" +"1998 competition in *Salon* magazine. For this set of examples,\n" +"we're going to be working in the writing subdirectory:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:34 +msgid "" +"~~~\n" +"$ cd\n" +"$ cd Desktop/data-shell/writing\n" +"$ cat haiku.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:41 +msgid "" +"~~~\n" +"The Tao that is seen\n" +"Is not the true Tao, until\n" +"You bring fresh toner.\n" +"\n" +"With searching comes loss\n" +"and the presence of absence:\n" +"\"My Thesis\" not found.\n" +"\n" +"Yesterday it worked\n" +"Today it is not working\n" +"Software is like that.\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:56 +msgid "> ## Forever, or Five Years" +msgstr "" + +#: shell-novice/_episodes/07-find.md:57 +msgid "" +">\n" +"> We haven't linked to the original haikus because they don't appear to be " +"on *Salon*'s site any longer.\n" +"> As [Jeff Rothenberg said](http://www.clir.org/pubs/archives/ensuring." +"pdf),\n" +"> \"Digital information lasts forever --- or five years, whichever comes " +"first.\"\n" +"> Luckily, popular content often [has backups](http://wiki.c2.com/?" +"ComputerErrorHaiku)." +msgstr "" + +#: shell-novice/_episodes/07-find.md:64 +msgid "Let's find lines that contain the word \"not\":" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:66 +msgid "" +"~~~\n" +"$ grep not haiku.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:71 +msgid "" +"~~~\n" +"Is not the true Tao, until\n" +"\"My Thesis\" not found\n" +"Today it is not working\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:78 +msgid "" +"Here, `not` is the pattern we're searching for. The grep command searches " +"through the file, looking for matches to the pattern specified. To use it " +"type `grep`, then the pattern we're searching for and finally the name of " +"the file (or files) we're searching in." +msgstr "" + +#: shell-novice/_episodes/07-find.md:80 +msgid "" +"The output is the three lines in the file that contain the letters \"not\"." +msgstr "" + +#: shell-novice/_episodes/07-find.md:82 +msgid "Let's try a different pattern: \"The\"." +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:84 +msgid "" +"~~~\n" +"$ grep The haiku.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:89 +msgid "" +"~~~\n" +"The Tao that is seen\n" +"\"My Thesis\" not found.\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:95 +msgid "" +"This time,\n" +"two lines that include the letters \"The\" are outputted.\n" +"However, one instance of those letters is contained within a larger word,\n" +"\"Thesis\"." +msgstr "" + +#: shell-novice/_episodes/07-find.md:100 +msgid "" +"To restrict matches to lines containing the word \"The\" on its own,\n" +"we can give `grep` with the `-w` flag.\n" +"This will limit matches to word boundaries." +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:104 +msgid "" +"~~~\n" +"$ grep -w The haiku.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:109 +msgid "" +"~~~\n" +"The Tao that is seen\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:114 +msgid "" +"Note that a \"word boundary\" includes the start and end of a line, so not\n" +"just letters surrounded by spaces. \n" +"Sometimes we don't\n" +"want to search for a single word, but a phrase. This is also easy to do " +"with\n" +"`grep` by putting the phrase in quotes." +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:120 +msgid "" +"~~~\n" +"$ grep -w \"is not\" haiku.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:125 +msgid "" +"~~~\n" +"Today it is not working\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:130 +msgid "" +"We've now seen that you don't have to have quotes around single words,\n" +"but it is useful to use quotes when searching for multiple words.\n" +"It also helps to make it easier to distinguish between the search term or " +"phrase\n" +"and the file being searched.\n" +"We will use quotes in the remaining examples." +msgstr "" + +#: shell-novice/_episodes/07-find.md:136 +msgid "Another useful option is `-n`, which numbers the lines that match:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:138 +msgid "" +"~~~\n" +"$ grep -n \"it\" haiku.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:143 +msgid "" +"~~~\n" +"5:With searching comes loss\n" +"9:Yesterday it worked\n" +"10:Today it is not working\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:150 +msgid "Here, we can see that lines 5, 9, and 10 contain the letters \"it\"." +msgstr "" + +#: shell-novice/_episodes/07-find.md:152 +msgid "" +"We can combine options (i.e. flags) as we do with other Unix commands.\n" +"For example, let's find the lines that contain the word \"the\". We can " +"combine\n" +"the option `-w` to find the lines that contain the word \"the\" and `-n` to " +"number the lines that match:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:156 +msgid "" +"~~~\n" +"$ grep -n -w \"the\" haiku.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:161 +msgid "" +"~~~\n" +"2:Is not the true Tao, until\n" +"6:and the presence of absence:\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:167 +msgid "Now we want to use the option `-i` to make our search case-insensitive:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:169 +msgid "" +"~~~\n" +"$ grep -n -w -i \"the\" haiku.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:174 +msgid "" +"~~~\n" +"1:The Tao that is seen\n" +"2:Is not the true Tao, until\n" +"6:and the presence of absence:\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:181 +msgid "" +"Now, we want to use the option `-v` to invert our search, i.e., we want to " +"output\n" +"the lines that do not contain the word \"the\"." +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:184 +msgid "" +"~~~\n" +"$ grep -n -w -v \"the\" haiku.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:189 +msgid "" +"~~~\n" +"1:The Tao that is seen\n" +"3:You bring fresh toner.\n" +"4:\n" +"5:With searching comes loss\n" +"7:\"My Thesis\" not found.\n" +"8:\n" +"9:Yesterday it worked\n" +"10:Today it is not working\n" +"11:Software is like that.\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:202 +msgid "" +"`grep` has lots of other options. To find out what they are, we can type:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:204 +msgid "" +"~~~\n" +"$ grep --help\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:209 +msgid "" +"~~~\n" +"Usage: grep [OPTION]... PATTERN [FILE]...\n" +"Search for PATTERN in each FILE or standard input.\n" +"PATTERN is, by default, a basic regular expression (BRE).\n" +"Example: grep -i 'hello world' menu.h main.c\n" +"\n" +"Regexp selection and interpretation:\n" +" -E, --extended-regexp PATTERN is an extended regular expression (ERE)\n" +" -F, --fixed-strings PATTERN is a set of newline-separated fixed " +"strings\n" +" -G, --basic-regexp PATTERN is a basic regular expression (BRE)\n" +" -P, --perl-regexp PATTERN is a Perl regular expression\n" +" -e, --regexp=PATTERN use PATTERN for matching\n" +" -f, --file=FILE obtain PATTERN from FILE\n" +" -i, --ignore-case ignore case distinctions\n" +" -w, --word-regexp force PATTERN to match only whole words\n" +" -x, --line-regexp force PATTERN to match only whole lines\n" +" -z, --null-data a data line ends in 0 byte, not newline\n" +"\n" +"Miscellaneous:\n" +"... ... ...\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:232 +msgid "> ## Using `grep`" +msgstr "" + +#: shell-novice/_episodes/07-find.md:233 +msgid "" +">\n" +"> Which command would result in the following output:\n" +">\n" +"> ~~~\n" +"> and the presence of absence:\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:240 +msgid "" +">\n" +"> 1. `grep \"of\" haiku.txt`\n" +"> 2. `grep -E \"of\" haiku.txt`\n" +"> 3. `grep -w \"of\" haiku.txt`\n" +"> 4. `grep -i \"of\" haiku.txt`\n" +">\n" +"> > ## Solution\n" +"> > The correct answer is 3, because the `-w` flag looks only for whole-word " +"matches.\n" +"> > The other options will all match \"of\" when part of another word." +msgstr "" + +#: shell-novice/_episodes/07-find.md:253 +msgid "" +">\n" +"> `grep`'s real power doesn't come from its options, though; it comes from\n" +"> the fact that patterns can include wildcards. (The technical name for\n" +"> these is **regular expressions**, which\n" +"> is what the \"re\" in \"grep\" stands for.) Regular expressions are both " +"complex\n" +"> and powerful; if you want to do complex searches, please look at the " +"lesson\n" +"> on [our website](http://v4.software-carpentry.org/regexp/index.html). As a " +"taster, we can\n" +"> find lines that have an 'o' in the second position like this:\n" +">\n" +"> ~~~\n" +"> $ grep -E '^.o' haiku.txt\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> ~~~\n" +"> You bring fresh toner.\n" +"> Today it is not working\n" +"> Software is like that.\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:273 +msgid "" +">\n" +"> We use the `-E` flag and put the pattern in quotes to prevent the shell\n" +"> from trying to interpret it. (If the pattern contained a `*`, for\n" +"> example, the shell would try to expand it before running `grep`.) The\n" +"> `^` in the pattern anchors the match to the start of the line. The `.`\n" +"> matches a single character (just like `?` in the shell), while the `o`\n" +"> matches an actual 'o'." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:282 +msgid "> ## Tracking a Species" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:284 +msgid "> Leah has several hundred " +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:285 +msgid "" +"> data files saved in one directory, each of which is formatted like this:" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:288 +msgid "> 2013-11-05,deer,5" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:289 +msgid "> 2013-11-05,rabbit,22" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:290 +msgid "> 2013-11-05,raccoon,7" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:291 +msgid "> 2013-11-06,rabbit,19" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:292 +msgid "> 2013-11-06,deer,2" +msgstr "" + +#: shell-novice/_episodes/07-find.md:295 +msgid "" +">\n" +"> She wants to write a shell script that takes a species as the first " +"command-line argument \n" +"> and a directory as the second argument. The script should return one file " +"called `species.txt` \n" +"> containing a list of dates and the number of that species seen on each " +"date.\n" +"> For example using the data shown above, `rabbits.txt` would contain:\n" +"> \n" +"> ~~~\n" +"> 2013-11-05,22\n" +"> 2013-11-06,19\n" +"> ~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:306 +msgid "" +">\n" +"> Put these commands and pipes in the right order to achieve this:\n" +"> \n" +"> ~~~\n" +"> cut -d : -f 2 \n" +"> > \n" +"> | \n" +"> grep -w $1 -r $2 \n" +"> | \n" +"> $1.txt \n" +"> cut -d , -f 1,3 \n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> Hint: use `man grep` to look for how to grep text recursively in a " +"directory\n" +"> and `man cut` to select more than one field in a line.\n" +">\n" +"> An example of such a file is provided in `data-shell/data/animal-counts/" +"animals.txt`\n" +">\n" +"> > ## Solution\n" +"> >\n" +"> > ```\n" +"> > grep -w $1 -r $2 | cut -d : -f 2 | cut -d , -f 1,3 > $1.txt\n" +"> > ```\n" +"> > {: .source}\n" +"> >\n" +"> > You would call the script above like this:\n" +"> >\n" +"> > ```\n" +"> > $ bash count-species.sh bear .\n" +"> > ```\n" +"> > {: .language-bash}" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:341 +msgid "> ## Little Women" +msgstr "" + +#: shell-novice/_episodes/07-find.md:342 +msgid "" +">\n" +"> You and your friend, having just finished reading *Little Women* by\n" +"> Louisa May Alcott, are in an argument. Of the four sisters in the\n" +"> book, Jo, Meg, Beth, and Amy, your friend thinks that Jo was the\n" +"> most mentioned. You, however, are certain it was Amy. Luckily, you\n" +"> have a file `LittleWomen.txt` containing the full text of the novel\n" +"> (`data-shell/writing/data/LittleWomen.txt`).\n" +"> Using a `for` loop, how would you tabulate the number of times each\n" +"> of the four sisters is mentioned?\n" +">\n" +"> Hint: one solution might employ\n" +"> the commands `grep` and `wc` and a `|`, while another might utilize\n" +"> `grep` options.\n" +"> There is often more than one way to solve a programming task, so a\n" +"> particular solution is usually chosen based on a combination of\n" +"> yielding the correct result, elegance, readability, and speed.\n" +">\n" +"> > ## Solutions\n" +"> > ```\n" +"> > for sis in Jo Meg Beth Amy\n" +"> > do\n" +"> > \techo $sis:\n" +"> >\tgrep -ow $sis LittleWomen.txt | wc -l\n" +"> > done\n" +"> > ```\n" +"> > {: .source}\n" +"> >\n" +"> > Alternative, slightly inferior solution:\n" +"> > ```\n" +"> > for sis in Jo Meg Beth Amy\n" +"> > do\n" +"> > \techo $sis:\n" +"> >\tgrep -ocw $sis LittleWomen.txt\n" +"> > done\n" +"> > ```\n" +"> > {: .source}\n" +"> >\n" +"> > This solution is inferior because `grep -c` only reports the number of " +"lines matched.\n" +"> > The total number of matches reported by this method will be lower if " +"there is more\n" +"> > than one match per line." +msgstr "" + +#: shell-novice/_episodes/07-find.md:385 +msgid "" +"While `grep` finds lines in files,\n" +"the `find` command finds files themselves.\n" +"Again,\n" +"it has a lot of options;\n" +"to show how the simplest ones work, we'll use the directory tree shown below." +msgstr "" + +#: shell-novice/_episodes/07-find.md:391 +msgid "![File Tree for Find Example](../fig/find-file-tree.svg)" +msgstr "" + +#: shell-novice/_episodes/07-find.md:393 +msgid "" +"Nelle's `writing` directory contains one file called `haiku.txt` and three " +"subdirectories:\n" +"`thesis` (which contains a sadly empty file, `empty-draft.md`);\n" +"`data` (which contains three files `LittleWomen.txt`, `one.txt` and `two." +"txt`);\n" +"and a `tools` directory that contains the programs `format` and `stats`,\n" +"and a subdirectory called `old`, with a file `oldtool`." +msgstr "" + +#: shell-novice/_episodes/07-find.md:399 +msgid "" +"For our first command,\n" +"let's run `find .`." +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:402 +msgid "" +"~~~\n" +"$ find .\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:407 +msgid "" +"~~~\n" +".\n" +"./data\n" +"./data/one.txt\n" +"./data/LittleWomen.txt\n" +"./data/two.txt\n" +"./tools\n" +"./tools/format\n" +"./tools/old\n" +"./tools/old/oldtool\n" +"./tools/stats\n" +"./haiku.txt\n" +"./thesis\n" +"./thesis/empty-draft.md\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:424 +msgid "" +"As always,\n" +"the `.` on its own means the current working directory,\n" +"which is where we want our search to start.\n" +"`find`'s output is the names of every file **and** directory\n" +"under the current working directory.\n" +"This can seem useless at first but `find` has many options\n" +"to filter the output and in this lesson we will discover some \n" +"of them." +msgstr "" + +#: shell-novice/_episodes/07-find.md:433 +msgid "" +"The first option in our list is\n" +"`-type d` that means \"things that are directories\".\n" +"Sure enough,\n" +"`find`'s output is the names of the six directories in our little tree\n" +"(including `.`):" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:439 +msgid "" +"~~~\n" +"$ find . -type d\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:444 +msgid "" +"~~~\n" +"./\n" +"./data\n" +"./thesis\n" +"./tools\n" +"./tools/old\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:453 +msgid "" +"Notice that the objects `find` finds are not listed in any particular " +"order.\n" +"If we change `-type d` to `-type f`,\n" +"we get a listing of all the files instead:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:457 +msgid "" +"~~~\n" +"$ find . -type f\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:462 +msgid "" +"~~~\n" +"./haiku.txt\n" +"./tools/stats\n" +"./tools/old/oldtool\n" +"./tools/format\n" +"./thesis/empty-draft.md\n" +"./data/one.txt\n" +"./data/LittleWomen.txt\n" +"./data/two.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:474 +msgid "Now let's try matching by name:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:476 +msgid "" +"~~~\n" +"$ find . -name *.txt\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:481 +msgid "" +"~~~\n" +"./haiku.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:486 +msgid "" +"We expected it to find all the text files,\n" +"but it only prints out `./haiku.txt`.\n" +"The problem is that the shell expands wildcard characters like `*` *before* " +"commands run.\n" +"Since `*.txt` in the current directory expands to `haiku.txt`,\n" +"the command we actually ran was:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:492 +msgid "" +"~~~\n" +"$ find . -name haiku.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:497 +msgid "`find` did what we asked; we just asked for the wrong thing." +msgstr "" + +#: shell-novice/_episodes/07-find.md:499 +msgid "" +"To get what we want,\n" +"let's do what we did with `grep`:\n" +"put `*.txt` in single quotes to prevent the shell from expanding the `*` " +"wildcard.\n" +"This way,\n" +"`find` actually gets the pattern `*.txt`, not the expanded filename `haiku." +"txt`:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:505 +msgid "" +"~~~\n" +"$ find . -name '*.txt'\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:510 +msgid "" +"~~~\n" +"./data/one.txt\n" +"./data/LittleWomen.txt\n" +"./data/two.txt\n" +"./haiku.txt\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:518 +msgid "> ## Listing vs. Finding" +msgstr "" + +#: shell-novice/_episodes/07-find.md:519 +msgid "" +">\n" +"> `ls` and `find` can be made to do similar things given the right options,\n" +"> but under normal circumstances,\n" +"> `ls` lists everything it can,\n" +"> while `find` searches for things with certain properties and shows them." +msgstr "" + +#: shell-novice/_episodes/07-find.md:526 +msgid "" +"As we said earlier,\n" +"the command line's power lies in combining tools.\n" +"We've seen how to do that with pipes;\n" +"let's look at another technique.\n" +"As we just saw,\n" +"`find . -name '*.txt'` gives us a list of all text files in or below the " +"current directory.\n" +"How can we combine that with `wc -l` to count the lines in all those files?" +msgstr "" + +#: shell-novice/_episodes/07-find.md:534 +msgid "The simplest way is to put the `find` command inside `$()`:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:536 +msgid "" +"~~~\n" +"$ wc -l $(find . -name '*.txt')\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:541 +msgid "" +"~~~\n" +"11 ./haiku.txt\n" +"300 ./data/two.txt\n" +"21022 ./data/LittleWomen.txt\n" +"70 ./data/one.txt\n" +"21403 total\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:550 +msgid "" +"When the shell executes this command,\n" +"the first thing it does is run whatever is inside the `$()`.\n" +"It then replaces the `$()` expression with that command's output.\n" +"Since the output of `find` is the four filenames `./data/one.txt`, `./data/" +"LittleWomen.txt`, `./data/two.txt`, and `./haiku.txt`,\n" +"the shell constructs the command:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:556 +msgid "" +"~~~\n" +"$ wc -l ./data/one.txt ./data/LittleWomen.txt ./data/two.txt ./haiku.txt\n" +"~~~" +msgstr "" + +#: shell-novice/_episodes/07-find.md:561 +msgid "" +"which is what we wanted.\n" +"This expansion is exactly what the shell does when it expands wildcards like " +"`*` and `?`,\n" +"but lets us use any command we want as our own \"wildcard\"." +msgstr "" + +#: shell-novice/_episodes/07-find.md:565 +msgid "" +"It's very common to use `find` and `grep` together.\n" +"The first finds files that match a pattern;\n" +"the second looks for lines inside those files that match another pattern.\n" +"Here, for example, we can find PDB files that contain iron atoms\n" +"by looking for the string \"FE\" in all the `.pdb` files above the current " +"directory:" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:571 +msgid "" +"~~~\n" +"$ grep \"FE\" $(find .. -name '*.pdb')\n" +"~~~" +msgstr "" + +# code block +#: shell-novice/_episodes/07-find.md:576 +msgid "" +"~~~\n" +"../data/pdb/heme.pdb:ATOM 25 FE 1 -0.924 0.535 -0.518\n" +"~~~" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:581 +msgid "> ## Matching and Subtracting" +msgstr "" + +#: shell-novice/_episodes/07-find.md:582 +msgid "" +">\n" +"> The `-v` flag to `grep` inverts pattern matching, so that only lines\n" +"> which do *not* match the pattern are printed. Given that, which of\n" +"> the following commands will find all files in `/data` whose names\n" +"> end in `s.txt` (e.g., `animals.txt` or `planets.txt`), but do\n" +"> *not* contain the word `net`?\n" +"> Once you have thought about your answer, you can test the commands in the " +"`data-shell`\n" +"> directory.\n" +">\n" +"> 1. `find data -name '*s.txt' | grep -v net`\n" +"> 2. `find data -name *s.txt | grep -v net`\n" +"> 3. `grep -v \"temp\" $(find data -name '*s.txt')`\n" +"> 4. None of the above.\n" +">\n" +"> > ## Solution\n" +"> > The correct answer is 1. Putting the match expression in quotes prevents " +"the shell\n" +"> > expanding it, so it gets passed to the `find` command.\n" +"> >\n" +"> > Option 2 is incorrect because the shell expands `*s.txt` instead of " +"passing the wildcard\n" +"> > expression to `find`.\n" +"> >\n" +"> > Option 3 is incorrect because it searches the contents of the files for " +"lines which\n" +"> > do not match \"temp\", rather than searching the file names." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:608 +msgid "> ## Binary Files" +msgstr "" + +#: shell-novice/_episodes/07-find.md:609 +msgid "" +">\n" +"> We have focused exclusively on finding things in text files. What if\n" +"> your data is stored as images, in databases, or in some other format?\n" +"> One option would be to extend tools like `grep` to handle those formats.\n" +"> This hasn't happened, and probably won't, because there are too many\n" +"> formats to support.\n" +">\n" +"> The second option is to convert the data to text, or extract the\n" +"> text-ish bits from the data. This is probably the most common approach,\n" +"> since it only requires people to build one tool per data format (to\n" +"> extract information). On the one hand, it makes simple things easy to\n" +"> do. On the negative side, complex things are usually impossible. For\n" +"> example, it's easy enough to write a program that will extract X and Y\n" +"> dimensions from image files for `grep` to play with, but how would you\n" +"> write something to find values in a spreadsheet whose cells contained\n" +"> formulas?\n" +">\n" +"> The third choice is to recognize that the shell and text processing have\n" +"> their limits, and to use another programming language.\n" +"> When the time comes to do this, don't be too hard on the shell: many\n" +"> modern programming languages have borrowed a lot of\n" +"> ideas from it, and imitation is also the sincerest form of praise." +msgstr "" + +#: shell-novice/_episodes/07-find.md:633 +msgid "" +"The Unix shell is older than most of the people who use it. It has\n" +"survived so long because it is one of the most productive programming\n" +"environments ever created --- maybe even *the* most productive. Its syntax\n" +"may be cryptic, but people who have mastered it can experiment with\n" +"different commands interactively, then use what they have learned to\n" +"automate their work. Graphical user interfaces may be better at the\n" +"first, but the shell is still unbeaten at the second. And as Alfred\n" +"North Whitehead wrote in 1911, \"Civilization advances by extending the\n" +"number of important operations which we can perform without thinking\n" +"about them.\"" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:644 +msgid "> ## `find` Pipeline Reading Comprehension" +msgstr "" + +#: shell-novice/_episodes/07-find.md:645 +msgid "" +">\n" +"> Write a short explanatory comment for the following shell script:\n" +">\n" +"> ~~~\n" +"> wc -l $(find . -name '*.dat') | sort -n\n" +"> ~~~\n" +"> {: .language-bash}\n" +">\n" +"> > ## Solution\n" +"> > 1. Find all files with a `.dat` extension in the current directory\n" +"> > 2. Count the number of lines each of these files contains\n" +"> > 3. Sort the output from step 2. numerically" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:660 +msgid "> ## Finding Files With Different Properties" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:662 +msgid "" +"> The `find` command can be given several other criteria known as \"tests\"" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:663 +msgid "" +"> to locate files with specific attributes, such as creation time, size," +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:664 +msgid "> permissions, or ownership. Use `man find` to explore these, and then" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:665 +msgid "" +"> write a single command to find all files in or below the current directory" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/_episodes/07-find.md:666 +msgid "> that were modified by the user `ahmed` in the last 24 hours." +msgstr "" + +#: shell-novice/_episodes/07-find.md:667 +msgid "" +">\n" +"> Hint 1: you will need to use three tests: `-type`, `-mtime`, and `-user`.\n" +">\n" +"> Hint 2: The value for `-mtime` will need to be negative---why?\n" +">\n" +"> > ## Solution\n" +"> > Assuming that Nelle’s home is our working directory we type:\n" +"> >\n" +"> > ~~~\n" +"> > $ find ./ -type f -mtime -1 -user ahmed\n" +"> > ~~~\n" +"> > {: .language-bash}" +msgstr "" + +# Front Matter +#: shell-novice/_extras/about.md:1 +msgid "" +"---\n" +"layout: page\n" +"title: About\n" +"permalink: /about/\n" +"---" +msgstr "" + +#: shell-novice/_extras/about.md:6 +msgid "{% include carpentries.html %}" +msgstr "" + +# Front Matter +#: shell-novice/_extras/discuss.md:1 +msgid "" +"---\n" +"layout: page\n" +"title: \"Discussion\"\n" +"permalink: /discuss/\n" +"---" +msgstr "" + +# header +#: shell-novice/_extras/discuss.md:6 +msgid "## Alphabet Soup" +msgstr "" + +#: shell-novice/_extras/discuss.md:8 +msgid "" +"If the command to find out who we are is `whoami`, the command to find\n" +"out where we are ought to be called `whereami`, so why is it `pwd`\n" +"instead? The usual answer is that in the early 1970s, when Unix was\n" +"first being developed, every keystroke counted: the devices of the day\n" +"were slow, and backspacing on a teletype was so painful that cutting the\n" +"number of keystrokes in order to cut the number of typing mistakes was\n" +"actually a win for usability. The reality is that commands were added to\n" +"Unix one by one, without any master plan, by people who were immersed in\n" +"its jargon. The result is as inconsistent as the roolz uv Inglish\n" +"speling, but we're stuck with it now." +msgstr "" + +# header +#: shell-novice/_extras/discuss.md:19 +msgid "## Job Control Codes" +msgstr "" + +#: shell-novice/_extras/discuss.md:21 +msgid "" +"The shell accepts a few special commands that allow users to interact\n" +"with running processes or programs. You can enter each of these\n" +"\"control codes\" by holding down the `Ctrl` key and then pressing one\n" +"of the control characters. In other tutorials, you may see the term\n" +"`Control` or the `^` used to represent the `Ctrl` key (e.g. the\n" +"following are all equivalent `Ctrl-C`, `Ctrl+C`, `Control-C`, `Control+C`, " +"`^C`)." +msgstr "" + +# unordered list +#: shell-novice/_extras/discuss.md:28 +msgid "* `Ctrl-C`:" +msgstr "" + +#: shell-novice/_extras/discuss.md:29 +msgid "" +" interrupts and cancels a running program.\n" +" This is useful if you want to cancel a command that is taking too long " +"to execute." +msgstr "" + +# unordered list +#: shell-novice/_extras/discuss.md:32 +msgid "* `Ctrl-D`:" +msgstr "" + +#: shell-novice/_extras/discuss.md:33 +msgid "" +" indicates the end of a file or stream of characters that you are " +"entering on the command line.\n" +" For example, we saw earlier that the `wc` command counts lines, words, " +"and characters in a file.\n" +" If we just type `wc` and hit the Enter key without providing a file " +"name,\n" +" then `wc` will assume we want it to analyze all the stuff we type next.\n" +" After typing our magnum opus directly into the shell prompt,\n" +" we can then type Ctrl-D to tell `wc` that we're done and we'd like to " +"see the results of the word count." +msgstr "" + +# unordered list +#: shell-novice/_extras/discuss.md:40 +msgid "* `Ctrl-Z`:" +msgstr "" + +#: shell-novice/_extras/discuss.md:41 +msgid "" +" Suspends a process but does not terminate it.\n" +" You can then use the command `fg` to restart the job in the foreground." +msgstr "" + +#: shell-novice/_extras/discuss.md:44 +msgid "" +"For new shell users, these control codes can all appear to have\n" +"the same effect: they make things \"go away.\" But it is helpful to\n" +"understand the differences. In general, if something went wrong and\n" +"you just want to get your shell prompt back, it is better to use\n" +"`Ctrl-C`." +msgstr "" + +# header +#: shell-novice/_extras/discuss.md:50 +msgid "## Other Shells" +msgstr "" + +#: shell-novice/_extras/discuss.md:52 +msgid "" +"Before Bash became popular in the end of nineties, scientists widely\n" +"used (and some still use) another shell, C-shell, or Csh. Bash and Csh\n" +"have similar feature sets, but their syntax rules are different and\n" +"this makes them incompatible with each other. A few other shells have\n" +"appeared since, including ksh, zsh, and a number of others; they are\n" +"mostly compatible with Bash, and Bash is the default shell on most\n" +"modern implementations of Unix (including most packages that provide\n" +"Unix-like tools for Windows) but if you get strange errors in shell\n" +"scripts written by colleagues, check to see which shell they were\n" +"written for." +msgstr "" + +# header +#: shell-novice/_extras/discuss.md:63 +msgid "## Bash Configurations" +msgstr "" + +#: shell-novice/_extras/discuss.md:65 +msgid "" +"Want to customize paths, environment variables, aliases,\n" +"and other behaviors of your shell?\n" +"This excellent blog post \"[Bash Configurations Demystified][bash-" +"demystified]\"\n" +"from Dalton Hubble\n" +"covers tips, tricks, and how to avoid dangers." +msgstr "" + +#: shell-novice/_extras/discuss.md:71 +msgid "" +"[bash-demystified]: https://blog.dghubble.io/post/.bashprofile-.profile-and-." +"bashrc-conventions/" +msgstr "" + +# Front Matter +#: shell-novice/_extras/figures.md:1 +msgid "" +"---\n" +"layout: page\n" +"title: Figures\n" +"---" +msgstr "" + +# inline html +#: shell-novice/_extras/figures.md:5 +msgid "" +"" +msgstr "" + +#: shell-novice/_extras/figures.md:34 shell-novice/aio.md:31 +msgid "" +"{% comment %}\n" +"Create anchor for each one of the episodes.\n" +"{% endcomment %}\n" +"{% for episode in site.episodes %}\n" +"
\n" +"{% endfor %}" +msgstr "" + +# Front Matter +#: shell-novice/_extras/guide.md:1 +msgid "" +"---\n" +"layout: page\n" +"title: \"Instructor Notes\"\n" +"permalink: /guide/\n" +"---" +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:6 +msgid "* Why do we learn to use the shell?" +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:7 +msgid " * Allows users to automate repetitive tasks" +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:8 +msgid "" +" * And capture small data manipulation steps that are normally not " +"recorded" +msgstr "" + +#: shell-novice/_extras/guide.md:9 +msgid "" +" to make research reproducible\n" +"* The Problem\n" +" * Running the same workflow on several samples can be unnecessarily " +"labour intensive\n" +" * Manual manipulation of data files:\n" +" * is often not captured in documentation\n" +" * is hard to reproduce\n" +" * is hard to troubleshoot, review, or improve\n" +"* The Shell\n" +" * Workflows can be automated through the use of shell scripts\n" +" * Built-in commands allow for easy data manipulation (e.g. sort, grep, " +"etc.)\n" +" * Every step can be captured in the shell script and allow " +"reproducibility and easy troubleshooting" +msgstr "" + +# header +#: shell-novice/_extras/guide.md:21 +msgid "## Overall" +msgstr "" + +#: shell-novice/_extras/guide.md:23 +msgid "" +"Many people have questioned whether we should still teach the shell.\n" +"After all,\n" +"anyone who wants to rename several thousand data files\n" +"can easily do so interactively in the Python interpreter,\n" +"and anyone who's doing serious data analysis\n" +"is probably going to do most of their work inside the IPython Notebook or R " +"Studio.\n" +"So why teach the shell?" +msgstr "" + +#: shell-novice/_extras/guide.md:31 +msgid "" +"The first answer is,\n" +"\"Because so much else depends on it.\"\n" +"Installing software,\n" +"configuring your default editor,\n" +"and controlling remote machines frequently assume a basic familiarity with " +"the shell,\n" +"and with related ideas like standard input and output.\n" +"Many tools also use its terminology\n" +"(for example, the `%ls` and `%cd` magic commands in IPython)." +msgstr "" + +#: shell-novice/_extras/guide.md:40 +msgid "" +"The second answer is,\n" +"\"Because it's an easy way to introduce some fundamental ideas about how to " +"use computers.\"\n" +"As we teach people how to use the Unix shell,\n" +"we teach them that they should get the computer to repeat things\n" +"(via tab completion,\n" +"`!` followed by a command number,\n" +"and `for` loops)\n" +"rather than repeating things themselves.\n" +"We also teach them to take things they've discovered they do frequently\n" +"and save them for later re-use\n" +"(via shell scripts),\n" +"to give things sensible names,\n" +"and to write a little bit of documentation\n" +"(like comment at the top of shell scripts)\n" +"to make their future selves' lives better." +msgstr "" + +#: shell-novice/_extras/guide.md:56 +msgid "" +"The third answer is,\n" +"\"Because it enables use of many domain-specific tools and compute resources " +"researchers cannot access otherwise.\"\n" +"Familiarity with the shell is very useful for remote accessing machines,\n" +"using high-performance computing infrastructure,\n" +"and running new specialist tools in many disciplines.\n" +"We do not teach HPC or domain-specific skills here\n" +"but lay the groundwork for further development of these skills.\n" +"In particular,\n" +"understanding the syntax of commands, flags, and help systems is useful for " +"domain specific tools\n" +"and understanding the file system (and how to navigate it) is useful for " +"remote access." +msgstr "" + +#: shell-novice/_extras/guide.md:67 +msgid "" +"Finally,\n" +"and perhaps most importantly,\n" +"teaching people the shell lets us teach them\n" +"to think about programming in terms of function composition.\n" +"In the case of the shell,\n" +"this takes the form of pipelines rather than nested function calls,\n" +"but the core idea of \"small pieces, loosely joined\" is the same." +msgstr "" + +#: shell-novice/_extras/guide.md:75 +msgid "" +"All of this material can be covered in three hours\n" +"as long as learners using Windows do not run into roadblocks such as:" +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:78 +msgid "* not being able to figure out where their home directory is" +msgstr "" + +#: shell-novice/_extras/guide.md:79 +msgid "" +" (particularly if they're using Cygwin);\n" +"* not being able to run a plain text editor;\n" +" and\n" +"* the shell refusing to run scripts that include DOS line endings." +msgstr "" + +# header +#: shell-novice/_extras/guide.md:84 +msgid "## Preparing to Teach" +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:86 +msgid "" +"* Use the `data` directory for in-workshop exercises and live coding " +"examples." +msgstr "" + +#: shell-novice/_extras/guide.md:87 +msgid "" +" You can clone the shell-novice directory or use the `Download ZIP`\n" +" button on the right to get the entire [repository](https://github.com/" +"swcarpentry/shell-novice). We also now provide\n" +" a zip file of the `data` directory that can be downloaded on its own\n" +" from the repository by right-click + save or see the [\"setup\"]" +"({{ page.root }}/setup/) page on the lesson website for more details. " +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:92 +msgid "* Website: various practices have been used." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:93 +msgid "" +" * Option 1: Can give links to learners before the lesson so they can " +"follow along," +msgstr "" + +#: shell-novice/_extras/guide.md:94 +msgid "" +" catch up,\n" +"\tand see exercises (particularly if you're following the lesson content " +"without many changes).\n" +" * Option 2: Don't show the website to the learners during the lesson, " +"as it can be distracting:\n" +" students may read instead of listen, and having another window open " +"is an additional cognitive load.\n" +"\t* In any case, make sure to point to website as a post-workshop " +"reference." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:100 +msgid "* Content:" +msgstr "" + +#: shell-novice/_extras/guide.md:101 +msgid "" +" Unless you have a truly generous amount of time (4+ hours),\n" +" it is likely that you will not cover ALL the material in this lesson in " +"a single half-day session.\n" +" Plan ahead on what you might skip, what you really want to emphasize, " +"etc." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:105 +msgid "* Exercises:" +msgstr "" + +#: shell-novice/_extras/guide.md:106 +msgid "" +" Think in advance about how you might want to handle exercises during the " +"lesson.\n" +" How are you assigning them (website, slide, handout)?\n" +" Do you want everyone to try it and then you show the solution?\n" +" Have a learner show the solution?\n" +" Have groups each do a different exercise and present their solutions?" +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:112 +msgid "" +"* `reference.md` can be printed out and given to students as a reference, " +"your choice." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:114 +msgid "* Other preparation:" +msgstr "" + +#: shell-novice/_extras/guide.md:115 +msgid "" +" Feel free to add your own examples or side comments,\n" +" but know that it shouldn't be necessary:\n" +" the topics and commands can be taught as given on the lesson pages.\n" +" If you think there is a place where the lesson is lacking,\n" +" feel free to file an issue or submit a pull request." +msgstr "" + +# header +#: shell-novice/_extras/guide.md:121 +msgid "## Teaching Notes" +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:123 +msgid "* Super cool online resource!" +msgstr "" + +#: shell-novice/_extras/guide.md:124 +msgid "" +" will dissect any shell command you type in\n" +" and display help text for each piece. Additional nice manual tool could " +"be with short very descriptive manuals for " +"shell commands, useful especially on Windows while using Git BASH where " +"`man` could not work." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:127 +msgid "* Another super cool online resource is ," +msgstr "" + +#: shell-novice/_extras/guide.md:128 +msgid "" +" which will check shell scripts (both uploaded and typed in) for common " +"errors." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:130 +msgid "* Resources for \"splitting\" your shell so that recent commands" +msgstr "" + +#: shell-novice/_extras/guide.md:131 +msgid "" +" remain in view: ." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:133 +msgid "* Running a text editor from the command line can be" +msgstr "" + +#: shell-novice/_extras/guide.md:134 +msgid "" +" the biggest stumbling block during the entire lesson:\n" +" many will try to run the same editor as the instructor\n" +" (which may leave them trapped in the awful nether hell that is Vim),\n" +" or will not know how to navigate to the right directory\n" +" to save their file,\n" +" or will run a word processor rather than a plain text editor.\n" +" The quickest way past these problems is to have more knowledgeable " +"learners\n" +" help those who need it." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:143 +msgid "* Introducing and navigating the filesystem in the shell (covered in" +msgstr "" + +#: shell-novice/_extras/guide.md:144 +msgid "" +" [Navigating Files and Directories]({{ page.root }}/02-filedir/) section) " +"can be confusing. You may have both terminal and GUI file explorer open side " +"by side so learners can see the content and file structure while they're " +"using terminal to navigate the system." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:146 +msgid "* Tab completion sounds like a small thing: it isn't." +msgstr "" + +#: shell-novice/_extras/guide.md:147 +msgid "" +" Re-running old commands using `!123` or `!wc`\n" +" isn't a small thing either,\n" +" and neither are wildcard expansion and `for` loops.\n" +" Each one is an opportunity to repeat one of the big ideas of Software " +"Carpentry:\n" +" if the computer *can* repeat it,\n" +" some programmer somewhere will almost certainly have built\n" +" some way for the computer *to* repeat it." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:155 +msgid "* Building up a pipeline with four or five stages," +msgstr "" + +#: shell-novice/_extras/guide.md:156 +msgid "" +" then putting it in a shell script for re-use\n" +" and calling that script inside a `for` loop,\n" +" is a great opportunity to show how\n" +" \"seven plus or minus two\"\n" +" connects to programming.\n" +" Once we have figured out how to do something moderately complicated,\n" +" we make it re-usable and give it a name\n" +" so that it only takes up one slot in working memory\n" +" rather than several.\n" +" It is also a good opportunity to talk about exploratory programming:\n" +" rather than designing a program up front,\n" +" we can do a few useful things\n" +" and then retroactively decide which are worth encapsulating\n" +" for future re-use." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:171 +msgid "* If everything is going well, you can drive home the point that file" +msgstr "" + +#: shell-novice/_extras/guide.md:172 +msgid "" +" extensions are essentially there to help computers (and human\n" +" readers) understand file content and are not a requirement of files\n" +" (covered briefly in [Navigating Files and Directories]({{ page." +"root }}/02-filedir/)).\n" +" This can be done in the [Pipes and Filters]({{ page.root }}/04-" +"pipefilter/) section by showing that you\n" +" can redirect standard output to a file without the .txt extension\n" +" (e.g., lengths), and that the resulting file is still a perfectly usable " +"text file.\n" +" Make the point that if double-clicked in the GUI, the computer will\n" +" probably ask you what you want to do." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:181 +msgid "" +"* We have to leave out many important things because of time constraints," +msgstr "" + +#: shell-novice/_extras/guide.md:182 +msgid "" +" including file permissions, job control, and SSH.\n" +" If learners already understand the basic material,\n" +" this can be covered instead using the online lessons as guidelines.\n" +" These limitations also have follow-on consequences:" +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:187 +msgid "* It's hard to discuss `#!` (shebang) without first discussing" +msgstr "" + +#: shell-novice/_extras/guide.md:188 +msgid "" +" permissions, which we don't do. `#!` is also [pretty\n" +" complicated][shebang], so even if we did discuss permissions, we\n" +" probably still wouldn't want to discuss `#!`." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:192 +msgid "* Installing Bash and a reasonable set of Unix commands on Windows" +msgstr "" + +#: shell-novice/_extras/guide.md:193 +msgid "" +" always involves some fiddling and frustration.\n" +" Please see the latest set of installation guidelines for advice,\n" +" and try it out yourself *before* teaching a class." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:197 +msgid "* On Windows machines" +msgstr "" + +#: shell-novice/_extras/guide.md:198 +msgid "" +" if `nano` hasn't been properly installed with the\n" +" [Software Carpentry Windows Installer][windows-installer]\n" +" it is possible to use `notepad` as an alternative. There will be a GUI\n" +" interface and line endings are treated differently, but otherwise, for\n" +" the purposes of this lesson, `notepad` and `nano` can be used almost " +"interchangeably." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:204 +msgid "* On Windows, it appears that:" +msgstr "" + +#: shell-novice/_extras/guide.md:206 +msgid "" +" ~~~\n" +" $ cd\n" +" $ cd Desktop\n" +" ~~~" +msgstr "" + +#: shell-novice/_extras/guide.md:212 +msgid "" +" will always put someone on their desktop.\n" +" Have them create the example directory for the shell exercises there\n" +" so that they can find it easily\n" +" and watch it evolve." +msgstr "" + +# unordered list +#: shell-novice/_extras/guide.md:217 +msgid "" +"* Stay within POSIX-compliant commands, as all the teaching materials do." +msgstr "" + +#: shell-novice/_extras/guide.md:218 +msgid "" +" Your particular shell may have extensions beyond POSIX that are not " +"available\n" +" on other machines, especially the default OSX bash and Windows bash " +"emulators.\n" +" For example, POSIX `ls` does not have an `--ignore=` or `-I` option, and " +"POSIX\n" +" `head` takes `-n 10` or `-10`, but not the long form of `--lines=10`." +msgstr "" + +# header +#: shell-novice/_extras/guide.md:223 +msgid "## Windows" +msgstr "" + +#: shell-novice/_extras/guide.md:225 +msgid "" +"Installing Bash and a reasonable set of Unix commands on Windows\n" +"always involves some fiddling and frustration.\n" +"Please see the latest set of installation guidelines for advice,\n" +"and try it out yourself *before* teaching a class.\n" +"Options we have explored include:" +msgstr "" + +# ordered list +#: shell-novice/_extras/guide.md:231 +msgid "1. [msysGit](http://msysgit.github.io/) (also called \"Git Bash\")," +msgstr "" + +# ordered list +#: shell-novice/_extras/guide.md:232 +msgid "2. [Cygwin](http://www.cygwin.com/)," +msgstr "" + +# ordered list +#: shell-novice/_extras/guide.md:233 +msgid "3. using a desktop virtual machine, and" +msgstr "" + +# ordered list +#: shell-novice/_extras/guide.md:234 +msgid "" +"4. having learners connect to a remote Unix machine (typically a VM in the " +"cloud)." +msgstr "" + +#: shell-novice/_extras/guide.md:236 +msgid "" +"Cygwin was the preferred option until mid-2013,\n" +"but once we started teaching Git,\n" +"msysGit proved to work better.\n" +"Desktop virtual machines and cloud-based VMs work well for technically " +"sophisticated learners,\n" +"and can reduce installation and configuration at the start of the workshop,\n" +"but:" +msgstr "" + +# ordered list +#: shell-novice/_extras/guide.md:243 +msgid "1. they don't work well on underpowered machines," +msgstr "" + +# ordered list +#: shell-novice/_extras/guide.md:244 +msgid "" +"2. they're confusing for novices (because simple things like copy and paste " +"work differently)," +msgstr "" + +# ordered list +#: shell-novice/_extras/guide.md:245 +msgid "" +"3. learners leave the workshop without a working environment on their " +"operating system of choice, and" +msgstr "" + +# ordered list +#: shell-novice/_extras/guide.md:246 +msgid "" +"4. learners may show up without having downloaded the VM or the wireless " +"will go down (or become congested) during the lesson." +msgstr "" + +#: shell-novice/_extras/guide.md:248 +msgid "" +"Whatever you use,\n" +"please *test it yourself* on a Windows machine *before* your workshop:\n" +"things may always have changed behind your back since your last workshop.\n" +"And please also make use of our\n" +"[Software Carpentry Windows Installer][windows-installer]." +msgstr "" + +#: shell-novice/_extras/guide.md:254 +msgid "" +"[shebang]: http://www.in-ulm.de/~mascheck/various/shebang/\n" +"[windows-installer]: {{ site.swc_github }}/windows-installer" +msgstr "" + +#: shell-novice/_includes/links.md:1 +msgid "" +"[cc-by-human]: https://creativecommons.org/licenses/by/4.0/\n" +"[cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode\n" +"[concept-maps]: http://carpentries.github.io/instructor-training/05-memory/\n" +"[email]: mailto:lessons@software-carpentry.org\n" +"[contrib-covenant]: http://contributor-covenant.org/\n" +"[contributing]: {{ site.github.repository_url }}/blob/gh-pages/CONTRIBUTING." +"md\n" +"[cran-checkpoint]: https://cran.r-project.org/web/packages/checkpoint/index." +"html\n" +"[cran-knitr]: https://cran.r-project.org/web/packages/knitr/index.html\n" +"[cran-stringr]: https://cran.r-project.org/web/packages/stringr/index.html\n" +"[github-importer]: https://import.github.com/\n" +"[importer]: https://github.com/new/import\n" +"[jekyll-collection]: https://jekyllrb.com/docs/collections/\n" +"[jekyll-install]: https://jekyllrb.com/docs/installation/\n" +"[jekyll-windows]: http://jekyll-windows.juthilo.com/\n" +"[jekyll]: https://jekyllrb.com/\n" +"[jupyter]: https://jupyter.org/\n" +"[mit-license]: http://opensource.org/licenses/mit-license.html\n" +"[morea]: https://morea-framework.github.io/\n" +"[numfocus]: http://numfocus.org/\n" +"[osi]: http://opensource.org\n" +"[pandoc]: https://pandoc.org/\n" +"[paper-now]: https://github.com/PeerJ/paper-now\n" +"[python-gapminder]: https://swcarpentry.github.io/python-novice-gapminder/\n" +"[pyyaml]: https://pypi.python.org/pypi/PyYAML\n" +"[r-markdown]: http://rmarkdown.rstudio.com/\n" +"[rstudio]: https://www.rstudio.com/\n" +"[ruby-install-guide]: https://www.ruby-lang.org/en/downloads/\n" +"[ruby-installer]: http://rubyinstaller.org/\n" +"[rubygems]: https://rubygems.org/pages/download/\n" +"[styles]: https://github.com/swcarpentry/styles/\n" +"[training]: http://swcarpentry.github.io/instructor-training/\n" +"[workshop-repo]: {{ site.workshop_repo }}\n" +"[yaml]: http://yaml.org/\n" +"[coc]: https://software-carpentry.org/conduct/\n" +"[coc-reporting]: https://software-carpentry.org/CoC-reporting/" +msgstr "" + +# Front Matter +#: shell-novice/aio.md:1 +msgid "" +"---\n" +"layout: page \n" +"root: .\n" +"---" +msgstr "" + +# inline html +#: shell-novice/aio.md:5 +msgid "" +"" +msgstr "" + +# Front Matter +#: shell-novice/index.md:1 +msgid "" +"---\n" +"layout: lesson\n" +"root: .\n" +"---" +msgstr "" + +#: shell-novice/index.md:6 +msgid "" +"The Unix shell has been around longer than most of its users have been " +"alive.\n" +"It has survived so long because it's a power tool\n" +"that allows people to do complex things with just a few keystrokes.\n" +"More importantly,\n" +"it helps them combine existing programs in new ways\n" +"and automate repetitive tasks\n" +"so they aren't typing the same things over and over again.\n" +"Use of the shell is fundamental to using a wide range of other powerful " +"tools \n" +"and computing resources (including \"high-performance computing\" " +"supercomputers).\n" +"These lessons will start you on a path towards using these resources " +"effectively." +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/index.md:17 +msgid "> ## Prerequisites" +msgstr "" + +#: shell-novice/index.md:18 +msgid "" +">\n" +"> This lesson guides you through the basics of file systems and the\n" +"> shell. If you have stored files on a computer at all and recognize\n" +"> the word “file” and either “directory” or “folder” (two common words\n" +"> for the same thing), you're ready for this lesson.\n" +">\n" +"> If you're already comfortable manipulating files and directories,\n" +"> searching for files with `grep` and `find`, and writing simple loops\n" +"> and scripts, you probably want to explore the next lesson: [shell-extras]" +"(swcarpentry.github.io/shell-extras)." +msgstr "" + +# SC/DC Template label +#: shell-novice/index.md:27 +msgid "{: .prereq}" +msgstr "" + +# Front Matter +#: shell-novice/reference.md:1 +msgid "" +"---\n" +"layout: reference\n" +"permalink: /reference/\n" +"---" +msgstr "" + +# header +#: shell-novice/reference.md:6 +msgid "## Summary of Basic Commands" +msgstr "" + +#: shell-novice/reference.md:8 +msgid "" +"| Action | Files | Folders |\n" +"|-------------|-------|--------------|\n" +"| Inspect | ls | ls |\n" +"| View content| cat | ls |\n" +"| Navigate to | | cd |\n" +"| Move | mv | mv |\n" +"| Copy | cp | cp -r |\n" +"| Create | nano | mkdir |\n" +"| Delete | rm | rmdir, rm -r |" +msgstr "" + +# header +#: shell-novice/reference.md:18 +msgid "## Filesystem hierarchy" +msgstr "" + +#: shell-novice/reference.md:20 +msgid "" +"The following is an overview of a standard Unix filesystem.\n" +"The exact hierarchy depends on the platform,\n" +"so you may not see exactly the same files/directories on your computer:" +msgstr "" + +#: shell-novice/reference.md:24 +msgid "![Linux filesystem hierarchy](../fig/standard-filesystem-hierarchy.svg)" +msgstr "" + +# header +#: shell-novice/reference.md:26 +msgid "## Glossary" +msgstr "" + +#: shell-novice/reference.md:28 +msgid "" +"{:auto_ids}\n" +"absolute path\n" +": A [path](#path) that refers to a particular location in a file system.\n" +" Absolute paths are usually written with respect to the file system's\n" +" [root directory](#root-directory),\n" +" and begin with either \"/\" (on Unix) or \"\\\\\" (on Microsoft " +"Windows).\n" +" See also: [relative path](#relative-path)." +msgstr "" + +#: shell-novice/reference.md:36 +msgid "" +"argument\n" +": A value given to a function or program when it runs.\n" +" The term is often used interchangeably (and inconsistently) with " +"[parameter](#parameter)." +msgstr "" + +#: shell-novice/reference.md:40 +msgid "" +"command shell\n" +": See [shell](#shell)" +msgstr "" + +#: shell-novice/reference.md:43 +msgid "" +"command-line interface\n" +": A user interface based on typing commands,\n" +" usually at a [REPL](#read-evaluate-print-loop).\n" +" See also: [graphical user interface](#graphical-user-interface)." +msgstr "" + +#: shell-novice/reference.md:48 +msgid "" +"comment\n" +": A remark in a program that is intended to help human readers understand " +"what is going on,\n" +" but is ignored by the computer.\n" +" Comments in Python, R, and the Unix shell start with a `#` character and " +"run to the end of the line;\n" +" comments in SQL start with `--`,\n" +" and other languages have other conventions." +msgstr "" + +#: shell-novice/reference.md:56 +msgid "" +"current working directory\n" +": The directory that [relative paths](#relative-path) are calculated " +"from;\n" +" equivalently,\n" +" the place where files referenced by name only are searched for.\n" +" Every [process](#process) has a current working directory.\n" +" The current working directory is usually referred to using the shorthand " +"notation `.` (pronounced \"dot\")." +msgstr "" + +#: shell-novice/reference.md:63 +msgid "" +"file system\n" +": A set of files, directories, and I/O devices (such as keyboards and " +"screens).\n" +" A file system may be spread across many physical devices,\n" +" or many file systems may be stored on a single physical device;\n" +" the [operating system](#operating-system) manages access." +msgstr "" + +#: shell-novice/reference.md:69 +msgid "" +"filename extension\n" +": The portion of a file's name that comes after the final \".\" " +"character.\n" +" By convention this identifies the file's type:\n" +" `.txt` means \"text file\", `.png` means \"Portable Network Graphics file" +"\",\n" +" and so on. These conventions are not enforced by most operating " +"systems:\n" +" it is perfectly possible (but confusing!) to name an MP3 sound file " +"`homepage.html`.\n" +" Since many applications use filename extensions to identify the [MIME " +"type](#mime-type) of the file,\n" +" misnaming files may cause those applications to fail." +msgstr "" + +#: shell-novice/reference.md:78 +msgid "" +"filter\n" +": A program that transforms a stream of data.\n" +" Many Unix command-line tools are written as filters:\n" +" they read data from [standard input](#standard-input),\n" +" process it, and write the result to [standard output](#standard-output)." +msgstr "" + +#: shell-novice/reference.md:84 +msgid "" +"flag\n" +": A terse way to specify an option or setting to a command-line program.\n" +" By convention Unix applications use a dash followed by a single letter,\n" +" such as `-v`, or two dashes followed by a word, such as `--verbose`,\n" +" while DOS applications use a slash, such as `/V`.\n" +" Depending on the application, a flag may be followed by a single " +"argument, as in `-o /tmp/output.txt`." +msgstr "" + +#: shell-novice/reference.md:91 +msgid "" +"for loop\n" +": A loop that is executed once for each value in some kind of set, list, " +"or range.\n" +" See also: [while loop](#while-loop)." +msgstr "" + +#: shell-novice/reference.md:95 +msgid "" +"graphical user interface\n" +": A user interface based on selecting items and actions from a graphical " +"display,\n" +" usually controlled by using a mouse.\n" +" See also: [command-line interface](#command-line-interface)." +msgstr "" + +#: shell-novice/reference.md:100 +msgid "" +"home directory\n" +": The default directory associated with an account on a computer system.\n" +" By convention, all of a user's files are stored in or below her home " +"directory." +msgstr "" + +#: shell-novice/reference.md:104 +msgid "" +"loop\n" +": A set of instructions to be executed multiple times. Consists of a [loop " +"body](#loop-body) and (usually) a\n" +" condition for exiting the loop. See also [for loop](#for-loop) and " +"[while loop](#while-loop)." +msgstr "" + +#: shell-novice/reference.md:108 +msgid "" +"loop body\n" +": The set of statements or commands that are repeated inside a [for loop]" +"(#for-loop)\n" +" or [while loop](#while-loop)." +msgstr "" + +#: shell-novice/reference.md:112 +msgid "" +"MIME type\n" +": MIME (Multi-Purpose Internet Mail Extensions) types describe different " +"file types for exchange on the Internet,\n" +" for example images, audio, and documents." +msgstr "" + +#: shell-novice/reference.md:116 +msgid "" +"operating system\n" +": Software that manages interactions between users, hardware, and software " +"[processes](#process). Common\n" +" examples are Linux, OS X, and Windows." +msgstr "" + +#: shell-novice/reference.md:120 +msgid "" +"orthogonal\n" +": To have meanings or behaviors that are independent of each other.\n" +" If a set of concepts or tools are orthogonal,\n" +" they can be combined in any way." +msgstr "" + +#: shell-novice/reference.md:125 +msgid "" +"parameter\n" +": A variable named in a function's declaration that is used to hold a " +"value passed into the call.\n" +" The term is often used interchangeably (and inconsistently) with " +"[argument](#argument)." +msgstr "" + +#: shell-novice/reference.md:129 +msgid "" +"parent directory\n" +": The directory that \"contains\" the one in question.\n" +" Every directory in a file system except the [root directory](#root-" +"directory) has a parent.\n" +" A directory's parent is usually referred to using the shorthand notation " +"`..` (pronounced \"dot dot\")." +msgstr "" + +#: shell-novice/reference.md:134 +msgid "" +"path\n" +": A description that specifies the location of a file or directory within " +"a [file system](#file-system).\n" +" See also: [absolute path](#absolute-path), [relative path](#relative-" +"path)." +msgstr "" + +#: shell-novice/reference.md:139 +msgid "" +"pipe\n" +": A connection from the output of one program to the input of another.\n" +" When two or more programs are connected in this way, they are called a " +"\"pipeline\"." +msgstr "" + +#: shell-novice/reference.md:143 +msgid "" +"process\n" +": A running instance of a program, containing code, variable values,\n" +" open files and network connections, and so on.\n" +" Processes are the \"actors\" that the [operating system](#operating-" +"system) manages;\n" +" it typically runs each process for a few milliseconds at a time\n" +" to give the impression that they are executing simultaneously." +msgstr "" + +#: shell-novice/reference.md:151 +msgid "" +"prompt\n" +": A character or characters display by a [REPL](#read-evaluate-print-loop) " +"to show that\n" +" it is waiting for its next command." +msgstr "" + +#: shell-novice/reference.md:155 +msgid "" +"quoting\n" +": (in the shell):\n" +" Using quotation marks of various kinds to prevent the shell from " +"interpreting special characters.\n" +" For example, to pass the string `*.txt` to a program,\n" +" it is usually necessary to write it as `'*.txt'` (with single quotes)\n" +" so that the shell will not try to expand the `*` wildcard." +msgstr "" + +#: shell-novice/reference.md:162 +msgid "" +"read-evaluate-print loop\n" +": (REPL): A [command-line interface](#command-line-interface) that reads a " +"command from the user,\n" +" executes it, prints the result, and waits for another command." +msgstr "" + +#: shell-novice/reference.md:166 +msgid "" +"redirect\n" +": To send a command's output to a file rather than to the screen or " +"another command,\n" +" or equivalently to read a command's input from a file." +msgstr "" + +#: shell-novice/reference.md:170 +msgid "" +"regular expression\n" +": A pattern that specifies a set of character strings.\n" +" REs are most often used to find sequences of characters in strings." +msgstr "" + +#: shell-novice/reference.md:174 +msgid "" +"relative path\n" +": A [path](#path) that specifies the location of a file or directory\n" +" with respect to the [current working directory](#current-working-" +"directory).\n" +" Any path that does not begin with a separator character (\"/\" or \"\\\\" +"\") is a relative path.\n" +" See also: [absolute path](#absolute-path)." +msgstr "" + +#: shell-novice/reference.md:180 +msgid "" +"root directory\n" +": The top-most directory in a [file system](#file-system).\n" +" Its name is \"/\" on Unix (including Linux and Mac OS X) and \"\\\\\" on " +"Microsoft Windows." +msgstr "" + +#: shell-novice/reference.md:184 +msgid "" +"shell\n" +": A [command-line interface](#cli) such as Bash (the Bourne-Again Shell)\n" +" or the Microsoft Windows DOS shell\n" +" that allows a user to interact with the [operating system](#operating-" +"system)." +msgstr "" + +#: shell-novice/reference.md:189 +msgid "" +"shell script\n" +": A set of [shell](#shell) commands stored in a file for re-use.\n" +" A shell script is a program executed by the shell;\n" +" the name \"script\" is used for historical reasons." +msgstr "" + +#: shell-novice/reference.md:195 +msgid "" +"standard input\n" +": A process's default input stream.\n" +" In interactive command-line applications,\n" +" it is typically connected to the keyboard;\n" +" in a [pipe](#pipe),\n" +" it receives data from the [standard output](#standard-output) of the " +"preceding process." +msgstr "" + +#: shell-novice/reference.md:203 +msgid "" +"standard output\n" +": A process's default output stream.\n" +" In interactive command-line applications,\n" +" data sent to standard output is displayed on the screen;\n" +" in a [pipe](#pipe),\n" +" it is passed to the [standard input](#standard-input) of the next " +"process." +msgstr "" + +#: shell-novice/reference.md:211 +msgid "" +"sub-directory\n" +": A directory contained within another directory." +msgstr "" + +#: shell-novice/reference.md:214 +msgid "" +"tab completion\n" +": A feature provided by many interactive systems in which\n" +" pressing the Tab key triggers automatic completion of the current word " +"or command." +msgstr "" + +#: shell-novice/reference.md:218 +msgid "" +"variable\n" +": A name in a program that is associated with a value or a collection of " +"values." +msgstr "" + +#: shell-novice/reference.md:221 +msgid "" +"while loop\n" +": A loop that keeps executing as long as some condition is true.\n" +" See also: [for loop](#for-loop)." +msgstr "" + +#: shell-novice/reference.md:225 +msgid "" +"wildcard\n" +": A character used in pattern matching.\n" +" In the Unix shell,\n" +" the wildcard `*` matches zero or more characters,\n" +" so that `*.txt` matches all files whose names end in `.txt`." +msgstr "" + +# header +#: shell-novice/reference.md:231 +msgid "## External references" +msgstr "" + +# header +#: shell-novice/reference.md:233 +msgid "### Opening a terminal" +msgstr "" + +# unordered list +#: shell-novice/reference.md:234 +msgid "" +"* [How to Use Terminal on a Mac](http://www.macworld.co.uk/feature/mac-" +"software/how-use-terminal-on-mac-3608274/)" +msgstr "" + +# unordered list +#: shell-novice/reference.md:235 +msgid "* [Git for Windows](https://git-for-windows.github.io/)" +msgstr "" + +# unordered list +#: shell-novice/reference.md:236 +msgid "" +"* [How to Install Bash shell command-line tool on Windows 10](https://www." +"windowscentral.com/how-install-bash-shell-command-line-windows-10)" +msgstr "" + +# unordered list +#: shell-novice/reference.md:237 +msgid "" +"* [Install and Use the Linux Bash Shell on Windows 10](https://www.howtogeek." +"com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/)" +msgstr "" + +# unordered list +#: shell-novice/reference.md:238 +msgid "" +"* [Using the Windows 10 Bash Shell](https://www.howtogeek.com/265900/" +"everything-you-can-do-with-windows-10s-new-bash-shell/)" +msgstr "" + +# unordered list +#: shell-novice/reference.md:239 +msgid "" +"* [Using a UNIX/Linux emulator (Cygwin) or Secure Shell (SSH) client (Putty)]" +"(http://faculty.smu.edu/reynolds/unixtut/windows.html)" +msgstr "" + +# header +#: shell-novice/reference.md:241 +msgid "### Manuals" +msgstr "" + +# unordered list +#: shell-novice/reference.md:242 +msgid "* [GNU manuals](http://www.gnu.org/manual/manual.html)" +msgstr "" + +# unordered list +#: shell-novice/reference.md:243 +msgid "" +"* [Core GNU utilities](http://www.gnu.org/software/coreutils/manual/" +"coreutils.html)" +msgstr "" + +# header +#: shell-novice/reference.md:245 +msgid "### Miscellaneous" +msgstr "" + +# unordered list +#: shell-novice/reference.md:246 +msgid "* [North Pacific Gyre](http://en.wikipedia.org/wiki/North_Pacific_Gyre)" +msgstr "" + +# unordered list +#: shell-novice/reference.md:247 +msgid "" +"* [Great Pacific Garbage Patch](http://en.wikipedia.org/wiki/" +"Great_Pacific_Garbage_Patch)" +msgstr "" + +# unordered list +#: shell-novice/reference.md:248 +msgid "" +"* ['Ensuring the longevity of digital information' by Jeff Rothenberg]" +"(http://www.clir.org/pubs/archives/ensuring.pdf)" +msgstr "" + +# unordered list +#: shell-novice/reference.md:249 +msgid "* [Computer error haikus](http://wiki.c2.com/?ComputerErrorHaiku)" +msgstr "" + +# Front Matter +#: shell-novice/setup.md:1 +msgid "" +"---\n" +"layout: page\n" +"title: Setup\n" +"root: .\n" +"---" +msgstr "" + +#: shell-novice/setup.md:7 +msgid "You need to download some files to follow this lesson:" +msgstr "" + +# ordered list +#: shell-novice/setup.md:9 +msgid "" +"1. Download [data-shell.zip]({{ page.root }}/data/data-shell.zip) and move " +"the file to your Desktop." +msgstr "" + +# ordered list +#: shell-novice/setup.md:10 +msgid "" +"2. Unzip/extract the file (ask your instructor if you need help with this " +"step). You should end up with a new folder called **data-shell** on your " +"Desktop." +msgstr "" + +# ordered list +#: shell-novice/setup.md:11 +msgid "" +"3. Open a terminal and type `cd`, then press the Enter key. That last step " +"will make sure you start with your home folder as your working directory." +msgstr "" + +#: shell-novice/setup.md:13 +msgid "" +"In the lesson, you will find out how to access the data in this folder. " +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/setup.md:15 +msgid "> ## Where to type commands: How to open a new shell" +msgstr "" + +# blockquote, which can be cascaded +#: shell-novice/setup.md:16 +msgid "" +"> The `shell` is a program that enables us to send commands to the computer " +"and receive output. It is also referred to as the `terminal` or `command " +"line`." +msgstr "" + +#: shell-novice/setup.md:17 +msgid "" +">\n" +"> Some computers include a default Unix Shell program. \n" +"> The steps below describe some methods for identifying and opening a Unix " +"Shell program if you already have one installed. \n" +"> There are also options for identifying and downloading a Unix Shell " +"program, a Linux/UNIX emulator, or a program to access a UNIX server. \n" +">\n" +"> If none of the options below address your circumstances, try an online " +"search for: UNIX shell [your computer model] [your operating system].\n" +">\n" +"> ### Linux\n" +"> The default shell for Linux operating systems is usually Bash.\n" +"> On most versions of Linux, it is accessible by running the Terminal " +"program,\n" +"> which can be found via the applications menu or the search bar. \n" +"> If your machine is set up to use something other than bash, you can run it " +"by opening a terminal and typing `bash`.\n" +">\n" +"> ### Mac OS\n" +"> For a Mac computer, the default Unix Shell is Bash,\n" +"> and it is available via the Terminal Utilities program within your " +"Applications folder.\n" +">\n" +"> To open Terminal, try one or both of the following:\n" +"> * Go to your Applications. Within Applications, open the Utilities folder. " +"Locate Terminal in the Utilities folder and open it.\n" +"> * Use the Mac ‘Spotlight’ computer search function. Search for: Terminal " +"and press [Enter] - this will open Terminal.\n" +">\n" +"> #### Reference \n" +"> [How to Use Terminal on a Mac](http://www.macworld.co.uk/feature/mac-" +"software/how-use-terminal-on-mac-3608274/)\n" +">\n" +"> ### Windows\n" +"> Computers with Windows operating systems do not automatically have a Unix " +"Shell program installed.\n" +"> In this lesson, we encourage you to use an emulator included in Git for " +"Windows, \n" +"> which gives you access to both Bash shell commands and Git. \n" +"> If you are attending a SWC session, it is likely you have already received " +"instructions on how to install Git for Windows.\n" +">\n" +"> Once installed, you can open a terminal by running the program Git Bash " +"from the Windows start menu.\n" +">\n" +"> Other solutions are available for running Bash commands on Windows " +"systems. \n" +"> There is now a Bash shell command-line tool available for Windows 10. \n" +"> Additionally, you can run Bash commands on a remote UNIX computer or " +"server from your Windows machine. \n" +"> This can be done through a Secure Shell (SSH) client. \n" +"> One such client available for free for Windows computers is PuTTY. \n" +"> See the reference below for information on installing and using PuTTY, \n" +"> using the Windows 10 command-line tool, or installing and using a UNIX/" +"Linux emulator.\n" +">\n" +"> #### Reference\n" +"> * [Git for Windows](https://git-for-windows.github.io/)\n" +"> * [How to Install Bash shell command-line tool on Windows 10](https://www." +"windowscentral.com/how-install-bash-shell-command-line-windows-10)\n" +"> * [Install and Use the Linux Bash Shell on Windows 10](https://www." +"howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-" +"windows-10/)\n" +"> * [Using the Windows 10 Bash Shell](https://www.howtogeek.com/265900/" +"everything-you-can-do-with-windows-10s-new-bash-shell/)\n" +"> * [Using a UNIX/Linux emulator (Cygwin) or Secure Shell (SSH) client " +"(Putty)](http://faculty.smu.edu/reynolds/unixtut/windows.html)" +msgstr "" diff --git a/python-ecology-lesson b/python-ecology-lesson new file mode 160000 index 00000000..10f38e36 --- /dev/null +++ b/python-ecology-lesson @@ -0,0 +1 @@ +Subproject commit 10f38e3621fddf1298367176e7a857500564ba6b