class: center, middle, inverse, title-slide # Data Science for Economists ## Lecture 2: Version control with Git(Hub) ### Grant McDermott ### University of Oregon |
EC 607
---  # Table of contents 1. [Prologue](#prologue) 2. [Git and GitHub](#git) 3. [Git(Hub) + RStudio](#rstudio) 4. [Git from the shell](#shell) 5. [Merge conflicts](#merge) 6. [Branches and forking](#branches) 7. [Other tips](#other) 8. [Summary](#summary) 9. [Appendix: FAQ](#faq) --- class: inverse, center, middle name: prologue # Prologue

 --- # Student presentation: R Markdown Resources: - Website: https://rmarkdown.rstudio.com - Cheatsheat: https://github.com/rstudio/cheatsheets/raw/master/rmarkdown-2.0.pdf - Book: [*R Markdown: The Definitive Guide*](https://bookdown.org/yihui/rmarkdown) (Yihui Xie, JJ Allaire, and Garrett Grolemund) Other points: - You will be submitting all of your assignments as R Markdown documents. - FWIW, my lecture slides and notes are all written in R Markdown too. (E.g. This slide deck is built using the [**xaringan**](https://github.com/yihui/xaringan/wiki) package with the metropolis theme.) --- # Before we start We went through a software installation check during the previous lecture. By now you should have: ☑ Installed [R](https://www.r-project.org/). ☑ Installed [RStudio](https://www.rstudio.com/products/rstudio/download/preview/). ☑ Installed [Git](https://git-scm.com/downloads). ☑ Created an account on [GitHub](https://github.com/) ☑ Accepted an invitation to EC 607 course repo (quarter specific).
 If in doubt about software, please consult Jenny Bryan's amazing guide: http://happygitwithr.com. --- class: inverse, center, middle name: git # Git and GitHub

 --- # Why bother?

 --- # Git(Hub) solves this problem ### Git - Git is a distributed version control system. (Wait, what?) - Okay, try this: Imagine if Dropbox and the "Track changes" feature in MS Word had a baby. Git would be that baby. - In fact, it's even better than that because Git is optimised for the things that economists and data scientists spend a lot of time working on (e.g. code). - There is a learning curve, but I promise you it's worth it. ### GitHub - It's important to realise that Git and GitHub are distinct things. - GitHub is an online hosting platform that provides an array of services built on top of the Git system. (Similar platforms include Bitbucket and GitLab.) - Just like we don't *need* Rstudio to run R code, we don't *need* GitHub to use Git... But it will make our lives so much easier. --- # Git(Hub) for scientific research ### From software development... Git and GitHub's role in global software development is not in question. - There's a high probability that your favourite app, program or package is built using Git-based tools. (RStudio is a case in point.) ### ... to scientific research Scientists and academic researchers are cottoning on too. - Benefits of VC and collaboration tools aside, Git(Hub) helps to operationalise the ideals of open science and reproducibility. - Journals have increasingly strict requirements regarding reproducibility and data access. GH makes this easy (DOI integration, off-the-shelf licenses, etc.) - I host all of the code and data for my [papers](http://grantmcdermott.com/research/) on GH. Same for teaching materials. I even use it to host and maintain my [website](https://github.com/grantmcdermott/grantmcdermott.github.io). - *Nature:* "[Democratic databases: science on GitHub](https://www.nature.com/news/democratic-databases-science-on-github-1.20719)" (Perkel, 2016). --- class: inverse, center, middle name: rstudio # Git(Hub) + RStudio

 --- # Seamless integration One of the (many) great features of RStudio is how well it integrates version control into your everyday workflow. - Even though Git is a completely separate program to R, they feel like part of the same "thing" in RStudio. - This next section is about learning the basic Git(Hub) commands and the recipe for successful project integration with RStudio. -- I also want to bookmark a general point that we'll revisit many times during this course: - The tools that we're using all form part of a coherent data science ecosystem. - Greatly reduces the cognitive overhead ("aggregation") associated with traditional workflows, where you have juggle multiple programs and languages at the same time. --- # Link a GitHub repo to an RStudio Project The starting point for our workflow is to link a GitHub repository (i.e. "repo") to an RStudio Project. Here are the steps we're going to follow: 1. Create the repo on GitHub and initialize with a README. 2. Copy the HTTPS/SSH link (the green "Clone or Download" button).1 3. Open up RStudio. 4. Navigate to **File -> New Project -> Version Control -> Git**. 5. Paste your copied link into the "Repository URL:" box. 6. Choose the project path ("Create project as subdirectory of:") and click **Create Project**. .footnote[1 It's easiest to start with HTTPS, but SSH is advised for more advanced users.] --
 Now, I want you to practice by these steps by creating your own repo on GitHub — call it "test" — and cloning it via an RStudio Project. - See my GIF walkthrough on the next slide... --- # Link a GitHub repo to an RStudio Project

 --- # Make some local changes Look at the top-right panel in your RStudio IDE. Do you see the "Git" tab? - Click on it. - There should already be some files in there, which we'll ignore for the moment.1 Now open up the README file (see the "Files" tab in the bottom-right panel). - Add some text like "Hello World!" and save the README. - Do you see any changes in the "Git" panel? Good. (Raise your hand if not.) Again, see my GIF walkthrough on the next slide... .footnote[1 They're important, but not for the purposes of this section.] --- # Make some local changes

 --- # Main Git operations Now that you've cloned your first repo and made some local changes, it's time to learn the four main Git operations. 1. **Stage** (or "add") - Tell Git that you want to add changes to the repo history (file edits, additions, deletions, etc.) 2. **Commit** - Tell Git that, yes, you are sure these changes should be part of the repo history. 3. **Pull** - Get any new changes made on the GitHub repo (i.e. the upstream remote), either by your collaborators or you on another machine. 4. **Push** - Push any (committed) local changes to the GitHub repo -- For the moment, it will be useful to group the first two operations and last two operations together. (They are often combined in practice too, although you'll soon get a sense of when and why they should be split up.) -- Ready for more GIFs? --- # Stage and Commit

 -- Note the helpful commit message to ourselves. --- # Push and Pull

 -- See [here](https://ohi-science.org/manual/#rpostback-askpass-error) if you get `Error: unable to read askpass response from 'rpostback-askpass'`. --- # Recap Here's a step-by-step summary of what we just did. - Made same changes to a file and saved them locally. - *Staged* these local changes. - *Committed* these local changes to our Git history with a helpful message. - *Pulled* from the GitHub repo just in case anyone else made changes too (not expected here, but good practice). - *Pushed* our changes to the GitHub repo.
 NB aside: Always pull from the upstream repo *before* you push any changes.  -- PS — You were likely challenged for your GitHub credentials at some point. Learn how to cache these [here](https://happygitwithr.com/credential-caching.html). -- PPS — Speaking of credentials, an even better approach is to [switch to SSH](https://happygitwithr.com/ssh-keys.html). I recommend you do this once you feel comfortable with the main Git operations. --- # Why this workflow? Creating the repo on GitHub first means that it will always be "upstream" of your (and any other) local copies. - In effect, this allows GitHub to act as the central node in the distributed VC network. - Especially valuable when you are collaborating on a project with others — more on this later — but also has advantages when you are working alone. - If you would like to move an existing project to GitHub, my advice is still to create an empty repo there first, clone it locally, and then copy all your files across. RStudio Projects are great. - Again, they interact seamlessly with Git(Hub), as we've just seen. - They also solve absolute vs. relative path problems, since the .Rproj file acts as an anchor point for all other files in the repo.1 .footnote[1 You know that calling files from `YourComputer/YourName/Documents/Special-Subfolder/etc` in your scripts makes you a bad person, right?] --- class: inverse, center, middle name: shell # Git from the shell

 --- # Why bother with the shell? The GitHub + RStudio Project combo is ideal for new users. - RStudio's Git integration and built-in GUI cover all the major operations. - RStudio Projects FTW. However, I want to go over Git shell commands so that you can internalise the basics. - The shell is more powerful and flexible. Does some things that the RStudio Git GUI can't. - Potentially more appropriate for projects that aren't primarily based in R. (Although, no real harm in using RStudio Projects to clone a non-R repo.) - Also, I'm kinda tired of screen recording animated GIFs. -- (Yes, we're going to cover the shell in depth next lecture, but think of this as a sneak preview.) --- # Main Git shell commands Clone a repo. ```bash $ git clone REPOSITORY-URL ``` See the commit history (hit spacebar to scroll down or q to exit). ```bash $ git log ``` What has changed? ```bash $ git status ``` --- # Main Git shell commands (cont.) Stage ("add") a file or group of files. ```bash $ git add NAME-OF-FILE-OR-FOLDER ``` You can use [wildcard](https://ryanstutorials.net/linuxtutorial/wildcards.php) characters to stage a group of files (e.g. sharing a common prefix). There are a bunch of useful flag options too: - Stage all files. ```bash $ git add -A ``` - Stage updated files only (modified or deleted, but not new). ```bash $ git add -u ``` - Stage new files only (not updated). ```bash $ git add . ``` --- # Main Git shell commands (cont.) Commit your changes. ```bash $ git commit -m "Helpful message" ``` Pull from the upstream repository (i.e. GitHub). ```bash $ git pull ``` Push any local changes that you've committed to the upstream repo (i.e. GitHub). ```bash $ git push ``` --- class: inverse, center, middle name: merge # Merge conflicts

 --- # Collaboration time Turn to the person next to you. You are now partners. (Congratulations.) - P1: Invite P2 to join you as a collaborator on the "test" GitHub repo that you created earlier. (See the *Settings* tab of your repo.) - P2: Clone P1's repo to your local machine.1 Make some edits to the README (e.g. delete lines of text and add your own). Stage, commit and push these changes. - P1: Make your own changes to the README on your local machine. Stage, commit and then try to push them (*after* pulling from the GitHub repo first). .footnote[1 Change into a new directory first or give it a different name to avoid conflicts with your own "test" repo. Don't worry, Git tracking will still work if you change the repo name locally.] -- Did P1 encounter a `merge conflict` error? - Good, that's what we were trying to trigger. - Now, let's learn how to fix them. --- # Merge conflicts Let's confirm what's going on. ```bash $ git status ``` As part of the response, you should see something like: ```bash Unmerged paths: (use "git add <file>..." to mark resolution) * both modified: README.md ``` Git is protecting P1 by refusing the merge. It wants to make sure that you don't accidentally overwrite all of your changes by pulling P2's version of the README. - In this case, the source of the problem was obvious. Once we start working on bigger projects, however, `git status` can provide a helpful summary to see which files are in conflict. --- # Merge conflicts (cont.) Okay, let's see what's happening here by opening up the README file. RStudio is a good choice, although your preferred text editor is fine.1 You should see something like: ```bash # README Some text here. <<<<<<< HEAD Text added by Partner 2. ======= Text added by Partner 1. >>>>>>> 814e09178910383c128045ce67a58c9c1df3f558. More text here. ``` .footnote[1 Other good choices are VS Code or Atom, which both support native Git(Hub) integration. You can set your preferred default editor with `$ git config --global core.editor "PREFERRED_EDITOR"`.] --- # Merge conflicts (cont.) What do these symbols mean? ```bash # README Some text here. <<<<<<< HEAD Text added by Partner 2. ======= Text added by Partner 1. >>>>>>> 814e09178910383c128045ce67a58c9c1df3f558. More text here. ``` --- count: false # Merge conflicts (cont.) What do these symbols mean? ```bash # README Some text here. *<<<<<<< HEAD Text added by Partner 2. ======= Text added by Partner 1. >>>>>>> 814e09178910383c128045ce67a58c9c1df3f558. More text here. ``` - `<<<<<<< HEAD` Indicates the start of the merge conflict. --- count: false # Merge conflicts (cont.) What do these symbols mean? ```bash # README Some text here. <<<<<<< HEAD Text added by Partner 2. *======= Text added by Partner 1. >>>>>>> 814e09178910383c128045ce67a58c9c1df3f558. More text here. ``` - `<<<<<<< HEAD` Indicates the start of the merge conflict. - `=======` Indicates the break point used for comparison. --- count: false # Merge conflicts (cont.) What do these symbols mean? ```bash # README Some text here. <<<<<<< HEAD Text added by Partner 2. ======= Text added by Partner 1. *>>>>>>> 814e09178910383c128045ce67a58c9c1df3f558. More text here. ``` - `<<<<<<< HEAD` Indicates the start of the merge conflict. - `=======` Indicates the break point used for comparison. - `>>>>>>> <long string>` Indicates the end of the lines that had a merge conflict. --- # Merge conflicts (cont.) Fixing these conflicts is a simple matter of (manually) editing the README file. - Delete the lines of the text that you don't want. - Then, delete the special Git merge conflict symbols. Once that's done, you should be able to stage, commit, pull and finally push your changes to the GitHub repo without any errors. -- Caveats - P1 gets to decide what to keep because they fixed the merge conflict. - OTOH, the full commit history is preserved, so P2 can always recover their changes if desired. - A more elegant and democratic solution to merge conflicts (and repo changes in general) is provided by Git **branches**. We'll get there next. --- # Aside: Line endings and different OSs ### Problem During your collaboration, you may have encountered a situation where Git is highlighting differences on seemingly unchanged sentences. - If that is the case, check whether your partner is using a different OS to you. The "culprit" is the fact that Git evaluates an invisible character at the end of every line. This is how Git tracks changes. (More info [here](https://help.github.com/articles/dealing-with-line-endings/) and [here](https://en.wikipedia.org/wiki/Newline).) - For Linux and MacOS, that ending is "LF" - For Windows, that ending is "CRLF" (of course it is...) ### Solution Open up the shell and enter ```bash $ git config --global core.autocrlf input ``` (Windows users: Change `input` to `true`). --- class: inverse, center, middle name: branches # Branches and forking

 --- # What are branches and why use them? Branches are one of Git's coolest features. - Allow you to take a snapshot of your existing repo and try out a whole new idea *without affecting* your main (i.e. "master") branch. - Only once you (and your collaborators) are 100% satisfied, would you merge it back into the master branch.1 - This is how most new features in modern software and apps are developed. - It is also how bugs are caught and fixed. - But researchers can easily — and should! — use it to try out new ideas and analysis (e.g. robustness checks, revisions, etc.) - If you aren't happy, then you can just delete the experimental branch and continue as if nothing happened. .footnote[1 You can actually have branches of branches (of branches). But let's not get ahead of ourselves.] -- I use branches all the time for my own research projects. --- # Create a new branch in RStudio

 --- # Branch shell commands Create a new branch on your local machine and switch to it: ```bash $ git checkout -b NAME-OF-YOUR-NEW-BRANCH ``` Push the new branch to GitHub: ```bash $ git push origin NAME-OF-YOUR-NEW-BRANCH ``` List all branches on your local machine: ```bash $ git branch ``` Switch back to (e.g.) the master branch: ```bash $ git checkout master ``` Delete a branch ```bash $ git branch -d NAME-OF-YOUR-FAILED-BRANCH $ git push origin :NAME-OF-YOUR-FAILED-BRANCH ``` --- # Merging branches + Pull requests You have two options: ### 1. Locally - Commit your final changes to the new branch (say we call it "new-idea"). - Switch back to the master branch: `$ git checkout master` - Merge in the new-idea branch changes: `$ git merge new-idea` - Delete the new-idea branch (optional): `$ git branch -d new-idea` ### 2. Remotely (i.e. *pull requests* on GitHub) - PRs are a way to notify collaborators — or yourself! — that you have completed a feature. - You write a summary of all the changes contained in the branch. - You then assign suggested reviewers of your code — including yourself potentially — who are then able to approve these changes ("Merge pull request") on GitHub. - Let's practice this now in class... --- # Your first pull request You know that "new-idea" branch we just created a few slides back? Switch over to it if you haven't already. - Remember: `$ git checkout new-idea` (or just click on the branches tab in RStudio) Make some local changes and then commit + push them to GitHub. - The changes themselves don't really matter. Add text to the README, add some new files, whatever. After pushing these changes, head over to your repo on GitHub. - You should see a new green button with "Compare & pull request". Click it. - Add a meta description of what this PR accomplishes. You can also change the title if you want. - Click "Create pull request". - (Here's where you or your collaborators would review all the changes.) - Once satisfied, click "Merge pull request" and then confirm. ??? See instructions here. --- # Your first pull request (cont.)

 --- # Forks Git forks lie somewhere between cloning a repo and branching from it. - In fact, if you fork a repo then you are really creating a copy of it. Forking a repo on GitHub is [very simple](https://help.github.com/articles/fork-a-repo/); just click the "Fork" button in the top-right corner of said repo. - This will create an independent copy of the repo under your GitHub account. - Try this now. Use one of [my repos](https://github.com/grantmcdermott?tab=repositories) if you can't think of anyone else's. Once you fork a repo, you are free to do anything you want to it. (It's yours.) However, forking — in combination with pull requests — is actually how much of the world's software is developed. For example: - Outside user *B* forks *A*'s repo. She adds a new feature (or fixes a bug she's identified) and then [issues an upstream pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). - *A* is notified and can then decide whether to merge *B*'s contribution with the main project. --- # Forks (cont.) Creating forks is super easy as we've just seen. However, maintaining them involves some more leg work if you want to stay up to date with the original repo. - GitHub: "[Syncing a fork](https://help.github.com/articles/syncing-a-fork/)" - OTOH, this isn't going to be an issue for completed projects. E.g. Forking the repo that contains the code and data of a published paper. -- ### OSS contribution Remember that "OSS contribution" component of the course (i.e. 10% of your final grade)? Well, now is a good time to tell you that forks, branches, and pull requests are effectively what I will be expecting of you. - Grades aside, I want to encourage you to start thinking about contributing to software projects in general. - Seriously, it can be something as simple as correcting typos or language. Many great programmers and data scientists are not English first-language speakers. Helping to improve package documentation is a small way to say thanks. (More [here](https://yihui.name/en/2013/06/fix-typo-in-documentation).) --- class: inverse, center, middle name: other # Other tips

 --- # README README files are special in GitHub because they act as repo landing pages. - For a project tied to a research paper, this is where you should be explicit about the goal of the research paper, the software requirements, how to run the analysis, and so forth (e.g. [here](https://github.com/grantmcdermott/bycatch)). - On the other end of the scale, many GitHub repos are basically standalone README files. Think of these as version-controlled blog posts (e.g. [here](https://github.com/jfiksel/github-classroom-for-teachers)). README files can also be added to the *sub-directories* of a repo, where they will act as a landing pages too. - Particularly useful for bigger projects. Say, where you are using multiple programming languages (e.g. [here](https://github.com/grantmcdermott/blueparadox)), or want to add more detail about a dataset (e.g. [here](https://github.com/grantmcdermott/sceptic-priors/tree/master/data)). READMEs should be written in Markdown, which GH automatically renders. - We'll learn more about [Markdown](https://www.markdownguide.org/) (and its close relation, [R Markdown](https://rmarkdown.rstudio.com/)) during the course of our homework assignments. --- # .gitignore A .gitignore file tells Git what to — *wait for it* — ignore. This is especially useful if you want to exclude whole folders or a class of files (e.g. based on size or type). - Proprietary data files should be ignored from the beginning if you intend to make a repo public at some point. - Very large individual files (>100 MB) exceed GitHub's maximum allowable size and should be ignored regardless. See here and here. I typically add compiled datasets to my .gitignore in the early stages of a project. - Reduces redundant version control history, where the main thing is the code that produces the compiled dataset, not the end CSV in of itself. ("Source is real.") - Simple to remove from my .gitignore once the project is being finalised (e.g. paper is being submitted). --- # .gitignore (cont.) You can create a .gitignore file in multiple ways. - A .gitignore file was automatically generated if you cloned your repo with an RStudio Project. - You could also have the option of adding one when you first create a repo on GitHub. - Or, you can create one with your preferred text editor. (Must be saved as ".gitignore".) Once the .gitignore file is created, simply add in lines of text corresponding to the files that should be ignored. - To ignore a single a file: `FILE-I-WANT-TO-IGNORE.csv` - To ignore a whole folder (and all of its contents, subfolders, etc.): `FOLDER-NAME/**` - The standard shell commands and special characters apply. - E.g. Ignore all CSV files in the repo: `*.csv` - E.g. Ignore all files beginning with "test": `test*` - E.g. Don't ignore a particular file: `!somefile.txt` --- # GitHub Issues [GitHub Issues](https://guides.github.com/features/issues/) are another great way to interact with your collaborators and/or package maintainers. - If you spot any problems with these lecture notes, please file an issue [here](https://github.com/uo-ec607/lectures/issues)! --- class: inverse, center, middle name: summary # Summary

 --- # Recipe (shell commands in grey) 1. Create a repo on GitHub and initialize with a README. 2. Clone the repo to your local machine. Preferably using an RStudio Project, but as you wish. (E.g. Shell command: `$ git clone REPOSITORY-URL`) 3. Stage any changes you make: `$ git add -A` 4.  Pull from GitHub: `$ git pull` 6. (Fix any merge conflicts.) 7. Push your changes to GitHub: `$ git push` -- Repeat steps 3—7 (but especially steps 3 and 4) often. --- # Coming up ### Get the course materials If you haven't done so already, now is a good time to clone/fork the course materials to your local computer. ### Assignment 1 Now that you've learned the necessary basics, Assignment 1 is up on GitHub Classroom. - Impress me with your ggplot2 skills. - Deadline: Due by the *start* of our next lecture. ### Next lecture Learning to love the shell... --- class: inverse, center, middle name: faq # Appendix: FAQ

 --- # FAQ **Q: When should I commit (and push) changes?** **A: Early and often.** - It's not quite as important as saving your work regularly, but it's a close second. - You should certainly push everything that you want your collaborators to see. **Q: Do I need branches if I am working on a solo project?** **A: You don't *need* them, but they offer big advantages in maintaining a sane workflow.** - Experiment without any risk to the main project! - If you combine them with pull requests, then you can compress significant additions to your project (which may comprise many small edits) into a single branch. --- # FAQ (cont.) **Q: What's the difference between cloning and forking a repo?** **A: Cloning directly ties your local version to the original repo, while forking creates a copy on your GitHub (which you can then clone).** - Cloning makes it easier to fetch updates (and is often the best choice for new GitHub users), but forking has advantages too.  - Seriously: http://ohshitgit.com/. **Q: What happens when something goes horribly wrong?** **A: Burn it down and start again.** - http://happygitwithr.com/burn.html - This is a great advantage of Git's distributed nature. If something goes horribly wrong, there's usually an intact version somewhere else. --- # FAQ (cont.)


Cucumber reached a million downloads in the first three years and 5 million downloads 3 years later. I'm happy to have created such a popular tool, but saddened to see how it's misused and misunderstood.
If you think Cucumber is a testing tool, please read on, because you are wrong.
Cucumber was born out of the frustration with ambiguous requirements and misunderstandings between the people who order the software and those who deliver it.
In 2003 I became part of a small clique of people from the XP community who were exploring better ways to do TDD. Dan North named this BDD. The idea was to combine automated acceptance tests, functional requirements and software documentation into one format that would be understandable by non-technical people as well as testing tools.
There was a lot of trial and error and in 2008 I created Cucumber to distill what I had learned into a nice little package. My vision was to provide a language, a process and a tool that would provide a single source of truth of software behaviour. The audience would be both non-technical and technical project members.
Unfortunately you can't just download Cucumber, start writing Cucumber Features and expect a nirvana of truth and enlightenment to happen on its own. There is a process to follow that involves many roles on the software team.
This process is called BDD. It's what came out of that clique I mentioned. BDD is not a tool you can download. Gojko Adzic gave BDD a new and better name: Specification by Example.
This process primarily consists of two activities (very simplified):
Specification Workshops (Three Amigos)
The people in charge of defining the requirements (business analysts) sit down with programmers and testers and discuss a feature to be implemented. (These roles are often called the three amigos). The three amigos come up with examples of how the software should behave, and write them down as Cucumber Scenarios.
Outside-In Development (Programmers)
Programmers run those Cucumber Scenarios with Cucumber, which tells them what needs to be implemented - what’s missing. They code a little bit, run Cucumber again and continue until the feature works as described.
The technique is called Outside-In because programmers typically start with the functionality that is closest to the user (the user interface, which is on the outside of the system) and gradually work towards the guts of the system (business logic, persistence, messaging and so on) as they discover more of what needs to be implemented.
This discovery is guided by failing tests, just like with TDD. The main difference is that Cucumber operates on a higher abstraction level, closer to the domain and farther away from classes and methods.
Early adopters
Most of the early adopters of Cucumber in 2008-2009 understood that Cucumber was intrinsically linked to this process. They would often wear all hats of the three amigos: Business analyst, programmer and tester. -Or they would be working in a team where everyone was more or less on board with the idea of BDD.
The Rails community derails
The second big batch of adopters was Rails developers (2009-2011). Automated testing was part of their culture, partly due to the testing tools embedded in Rails. Many of them saw Cucumber as a better automated testing tool, but most of them completely missed out on the underlying practices such as Specification Workshops with the three amigos and Outside In Development.
What many didn't realise was that Cucumber was now taken out of its intended context: Collaboration.
When Cucumber is adopted solely as a tool to write automated tests without any input from business analysts they tend to become imperative and lose their documentation value.
This also makes them slow and brittle.
I’m partly to blame for this since I equipped Cucumber with training wheels. Mea culpa.
There is a certain amount of ceremony involved with Cucumber. There is both Gherkin and Step Definitions to maintain. This can be justified if it improves collaboration and reduces misunderstandings, but if the tool is used in a vacuum those benefits will obviously never happen.
This improper usage of Cucumber caused many Rails teams to reject Cucumber. It's an interesting thread. The vast majority doesn't realise that Cucumber is a collaboration tool.
Testing community
When Matt Wynne and I published a book about Cucumber in 2011 it ended up on the radar of larger organisations that employ dedicated testers. These are people who are used to manual testing, enterprise tools such as HP Quality Center / ALM and to some degree other open source automation tools like Selenium.
This crowd has pretty much fallen into the same trap as the Rails developers - they use Cucumber uniquely as a testing tool. No collaboration. No outside-in.
They write Cucumber scenarios after the software instead of the other way around. Doing BDD well leads to decoupled software, which again makes it easy to reduce the duration of tests. You don't get any of these benefits when you treat Cucumber as an afterthought.
Doing it right
Andrew Premdas, one of the first adopters of Cucumber, says it well:
Your cucumber features should drive your implementation, not reflect it.
Think about that for a minute. This has a lot of implications. First of all, it means Cucumber features should be written before the code implementing the feature.
This takes us back to the Venn diagram in the beginning of this post. Cucumber features start their life as software requirements. The most important contributors to requirements aren’t programmers or testers - it’s business analysts. During this activity the programmers’ and testers’ primary responsibility is to ask questions and make sure they understand everything.
Tests fall out of BDD
When you do BDD/Specification by Example and Outside-in, regression tests fall out at the other end. They are a by-product of those activities. Testing isn't the activity itself.
Cucumber is first a formost a collaboration tool that aims to bring a common understanding to software teams - across roles.
For many teams it isn’t lack of understanding of BDD or Specification by Example that is the biggest barrier. It’s simply inappropriate tooling.
Programmers and testers are comfortable with development tools. Most business analysts are not. Cucumber is a development tool, and therefore many business analysts won’t touch it with a ten feet pole.
This is part of the reason why I co-founded Cucumber Ltd and our flagship product, Cucumber Pro. Our goal is to provide a collaboration tool for Cucumber that is as easy to use as a word processor or social networking website.
We also offer training via Kickstart Academy for teams who want to learn how to apply BDD and Specification by Example.
I am very excited about the future of Cucumber. I hope more teams will start to use it the way it was intended to be used.


demmlp1
x1
is sampled uniformly from the range (0,1) and has
a low level of added Gaussian noise, x2
is a copy of x1
with a higher level of added noise, and x3
is sampled randomly
from a Gaussian distribution. The single target variable is determined
by sin(2*pi*x1)
with additive Gaussian noise. Thus x1
is
very relevant for determining the target value, x2
is of some
relevance, while x3
is irrelevant. The prior over weights is
given by the ARD Gaussian prior with a separate hyper-parameter for
the group of weights associated with each input. A multi-layer
perceptron is trained on this data, with re-estimation of the
hyper-parameters using evidence
. The final values for the
hyper-parameters reflect the relative importance of the three inputs.
demmlp1
, demev1
, mlp
, evidence
Copyright (c) Ian T Nabney (1996-9)


Chart 1
Chart 2
Dublin Bike Station usage rate on Rain and Non-Rain days (RedColor: Rain, GreyColor: Non-Rain)
This is the forecast for Dublin Bike Stations
This part of code will display 24hrs weather forecast. It takes data from JSON file and
triggers using OnClick method


{{define "Navbar"}}
{{end}} {{define "body"}}Friday, June 20 from 6-8pm with Lauren Sims
Bask in the longest day of the year with a simple "Flow & Glow" workshop with Lauren. Enjoy a sweet, stretchy active practice and then melt right into 45 minutes of restorative Yin Yoga. We'll close with guided meditation and savasana to help us enjoy the full savor of summer.
$25


Ever wonder how you can run one single test with gradlew? Ever get tried of waiting all the tests to be finished? You have came to the right place. Running tests can be a time consuming tasks. Ability to run one single test or all the tests in a test class is very powerful. And, it will save TONS of time. Here is how you can do it.
Let’s assume that this is your testClass,
package io.github.poanchen.projectName.api
class BlogControllerTests {
void testCreate_BlogWithoutTitle() {
// some test code
}
void testUpdate_BlogWithInvalidAuthorEmail() {
// some test code
}
}
To run single test (testCreate_BlogWithoutTitle),
./gradlew :projectName-api:unitTest --tests io.github.poanchen.projectName.api.BlogControllerTests.testCreate_BlogWithoutTitle
Note: Depends on how you write your configuration file for gradlew tasks, “:projectName-api:unitTest” might look different for you than the one that I show you here.
To run all the tests in a test class (BlogControllerTests),
./gradlew :projectName-api:unitTest --tests io.github.poanchen.projectName.api.BlogControllerTests
Tada. You should now be able to run a single test or all the tests in a test class with gradlew =)
Wrapping Up
Hopefully this guide has help you to learn how to run tests with gradlew. Thank you for reading!
Resources
I’ll try to keep this list current and up to date. If you know of a great resource you’d like to share or notice a broken link, please let us know.


"EAR "used frequently in a figurative sense (Psalm 34:15). To “uncover the ear” is to show respect to a person (1 Samuel 20:2 marg.). To have the “ear heavy”, or to have “uncircumcised ears” (Isaiah 6:10), is to be inattentive and disobedient. To have the ear “bored” through with an awl was a sign of perpetual servitude (Exodus 21:6).
"EAR "used frequently in a figurative sense (Psalm 34:15). To “uncover the ear” is to show respect to a person (1 Samuel 20:2 marg.). To have the “ear heavy”, or to have “uncircumcised ears” (Isaiah 6:10), is to be inattentive and disobedient. To have the ear “bored” through with an awl was a sign of perpetual servitude (Exodus 21:6).


Progress bar color scheme
Level 0 – Available for Reuse/Not Evaluated
- Asset is added to the Storefront for reuse or consumption. Asset has not been evaluated for Enterprise readiness or Conformance.
- Asset will enter DI2E Clearinghouse Process to be assessed for potential reuse.
- Asset has completed the Component Prep and Analysis phase.
Level 1 – Initial Reuse Analysis
- Inspection portion of DI2E Framework Evaluation Checklist complete.
- These questions focus mainly on the reuse potential (Visible, Accessible, and Understandable) by analysis of the information provided.
- This level does not represent the pass or fail, the Consumer must read the Evaluation Report.
Level 2 – Integration and Test
- Integration and Test portion of the DI2E Framework Evaluation Checklist complete.
- These questions focus on the interoperability and ease of reuse, and will normally include an I&T plan.
- This level does not indicate a pass or fail of the conformance test.
- Consumer will read the Test Report linked in the storefront entry for program functionality.
Level 3 – DI2E Framework Reference Implementation
- Asset has been determined to be reusable and interoperable, appropriately documented, and conformant to applicable DI2E Framework specifications and standards and is integrated into the DI2E Reference Ecosystem.
NA – No Evaluation Planned
- Planned Evaluation does not apply to DI2E Priorities, Focus Areas, Reference Architecture, Storefront (e.g. Guidebooks, reusable Contract Language, Lessons Learned, etc.).
- N/A indicates no evaluation is expected.


Ever growing like its historical surroundings; Neighborhood Commons Cooperative was built in 1978 originally as a Section 236 Complex, over the years of work and community cultivation evolved into a Cooperative in 1996, and is currently a moderate income property.
For decades NCC has contributed and connected to this community of spectacular schools, unique boutiques, beautiful parks, safe streets, socially conscious residents and flourishing families. The Cooperative "is not subsidized" by HUD or any other government agency.
MORE HISTORY COMING SOON.


--- layout: default title: Shreyas Pandya Blog Archive page-class: page--archive permalink: /archive/ ---


Legacy Survey Exposure QA
help
g band
r band
z band
Waiting for the help text to load. In case this fails, you can also view it
here
.
OK
Link


Vehicles were objects that became, in effect, mobile rooms… The code for the boat itself was not designed to function outside the river section, but nothing kept the player from carrying the deflated boat to the reservoir and trying to sail across…
— Tim Anderson, The History of Zork
Quite so. Even the case of an entirely static object which can be
climbed into or onto poses problems of realism. Sitting on a garden
roller, is one in the gardens, or not? Can one reasonably reach to
pick up a leaf on the ground? The Inform library leaves most of these
subtleties to the designer but has at least a general concept of
“enterable object”. These have enterable
and
the Enter
and Exit
actions allow the
player to get in (or on) and out (or off) of them.
Enterable items might include, say, an open-topped car, a
psychiatrist's couch or even a set of manacles attached to a dungeon
wall. In practice, though, manacles are an exceptional case, and
one usually wants to make an enterable
thing also a container
,
or – as in the case of the altar from ‘Ruins’
which appeared in the previous section – a supporter
:
Object -> stone_table "slab altar" with name 'stone' 'table' 'slab' 'altar' 'great', initial "A great stone slab of a table, or altar, dominates the Shrine.", has enterable supporter static;
A chair to sit on, or a bed to lie down on, should
also be a supporter
.
Sitting on furniture, one is hardly in a different location altogether.
But suppose the player climbs into a container
which is not transparent
and then closes it from the inside? To all intents and purposes this
has become another room. The interior may be dark, but if there's
light to see by, the player will want to see some kind of room description.
In any case, many enterable objects ought to look different from inside
or on top. Inside a vehicle, a player might be able to see a steering
wheel and a dashboard, for instance. On top of a cupboard, it might
be possible to see through a skylight window.
For this purpose, any enterable
object can provide a property called
inside_description
, which can hold a string of text or
else a routine to print some text, as usual.
If the exterior location is still visible, then the “inside
description” is appended to the normal room description; if
not, it replaces the
room description altogether. As an extreme example,
suppose that the player gets into a huge cupboard, closes the door
and then gets into a plastic cabinet inside that. The resulting room
description might read like so:
The huge cupboard (in the plastic cabinet)
It's a snug little cupboard in here, almost a room in itself.
In the huge cupboard you can see a pile of clothes.
The plastic walls of the cabinet distort the view.
The second line is the inside_description
for the huge cupboard, and the fourth is that for the plastic cabinet.
•
EXERCISE 22
(Also from ‘Ruins’.) Implement a cage which can be opened,
closed and entered.
· · · · ·
All the classic games have vehicles (like boats, or fork lift trucks, or hot air balloons) which the player can journey in, and Inform makes this easy. Here is a simple case:
Object car "little red car" cave with name 'little' 'red' 'car', description "Large enough to sit inside. Among the controls is a prominent on/off switch. The numberplate is KAR 1.", when_on "The red car sits here, its engine still running.", when_off "A little red car is parked here.", before [; Go: if (car has on) "Brmm! Brmm!"; print "(The ignition is off at the moment.)^"; ], has switchable enterable static container open;
Actually, this demonstrates a special rule. If
a player is inside an enterable
object and tries to
move, say “north”, the before routine for the object
is called with the action Go n_obj
. It may then return:
0 to disallow the movement, printing a refusal;
1 to allow the movement, moving vehicle and player;
2 to disallow but print and do nothing; or
3 to allow but print and do nothing.
If you want to move the vehicle in your own code,
return 3, not 2: otherwise the old location may be restored by subsequent
workings. Notice that if you write no code, the default value false
will always be returned, so enterable objects won't become
vehicular unless you write them that way.
▲ Because you might want to drive the car “out” of a garage, the “out” verb does not make the player get out of the car. Instead the player generally has to type something like “get out” or “exit” to make this happen.
•
EXERCISE 23
Alter the car so that it will only drive along roads, and not through
all map connections.
· · · · ·
Objects like the car or, say, an antiquated wireless
on casters, are too heavy to pick up but the player should at least
be able to push them from place to place. When the player tries to
do this, an action like PushDir wireless
is generated.
Now, if the before
routine for the
wireless returns false
, the game will just say that
the player can't move the wireless; and if it returns true
,
the game will do nothing at all, assuming that the before
routine has already printed something more interesting. So how does
one actually tell Inform that the push should be allowed? The answer
is: first call the AllowPushDir
routine (a library
routine), and then return true. For example (‘Ruins’
again), here is a ball on a north-south corridor which slopes upward
at the northern end:
Object -> huge_ball "huge pumice-stone ball" with name 'huge' 'pumice' 'pumice-stone' 'stone' 'ball', description "A good eight feet across, though fairly lightweight.", initial "A huge pumice-stone ball rests here, eight feet wide.", before [; PushDir: if (location == Junction && second == ne_obj) "The Shrine entrance is far less than eight feet wide."; AllowPushDir(); rtrue; Pull, Push, Turn: "It wouldn't be so very hard to get rolling."; Take, Remove: "There's a lot of stone in an eight-foot sphere."; ], after [; PushDir: if (second == s_obj) "The ball is hard to stop once underway."; if (second == n_obj) "You strain to push the ball uphill."; ], has static;
•
EXERCISE 24
The library does not normally allow pushing objects up or down. How
can the pumice ball allow this?
•
REFERENCES
For an enterable supporter
puzzle, see the magic carpet in
‘Balances’ (and several items in ‘Alice Through
the Looking-Glass’).
•When a vehicle has a sealed
interior large enough to be a location, it is probably best handled
as a location with changing map connections and not as a vehicle
object moved from room to room. See for instance Martin Braun's
"elevator.inf" example game, providing an elevator
which serves eight floors of a building.


Snack-Machine
Chewig-Gum (0.50JD)
10
Money Inside Machine
0
Chips (1.0JD)
10
Money In Transaction
0
Chockolate (2.0JD)
10
Change
0
BUY
CANCEL
0.25JD
0.50JD
1.0JD
5.0JD
10.0JD


Vanessa Stevenson
Food enthusiast, photography fan. Add a pinch of raw foodism and that's pretty much who I am.
Chocolate Pizza
POSTED ON 15 DEC 2013 / DESSERTS
For the fig-swirl: Melt butter over medium heat in a saucepan. Add brown sugar and stir to dissolve. Halve all of the figs and toss in the saucepan with water and lemon juice. Cook over medium heat, stirring frequently, until you have a chunky-jammy mixture. Add salt with one or two stirs, set aside and let cool completely.
Ice cream: In a small pot over medium heat, combine milk, and granulated sugar until sugar is completely dissolved and the milk is jut barely lukewarm. Whisk in the egg yolks. Set mixtures in the fridge and wait until the fig mixture is cooled.
Using an ice cream machine, pour liquids ito the frozen basin and process according to manufacturer instructions, i.e., let spin and thicken for 20 minutes before adding mascarpone, fig jam mixture, and the nuts. Continue to process for +/- 10 minutes. Pour semi-frozen mixture into a pyrex dish or glass tupperware. Freeze for at least two hours before serving.
- 1 1/2 cups milk
- 1/2 cup mascarpone
- 1/2 tsp pink salt
- 1 lb Black Mission Figs
- 1/2 cup brown sugar
- 2-4 tbsp water
- 1 1/2 cups heavy cream
- 1/3 granulated sugar
- 2 egg yolks
- 1 lemon, juiced
- 2 tbsp butter
- 1 cup honey roasted pecans, roughly chopped


Need professional moving services at a reasonable price from movers who care? Contact Big Mitten Moving Today!
Instant Move Estimate!We move furniture to and from your moving destination. Contact us today for a free quote. Residential moves typically start at $180.
Contact us at<PHONE_NUMBER>We can move you anywhere from the east coast to the west coast no matter the destination. Contact us today for a free quote. Out of State moves typically start at $250.
Contact us at<PHONE_NUMBER>Moving offices? Need new office furniture and equipment picked up or removed? Contact us today for a free quote.
Contact us at<PHONE_NUMBER>


{% extends 'marketplace/base.html' %} {% block pagecontents %}
We've emailed you instructions for setting your password, if an account exists with the email you entered. You should receive them shortly.
If you don't receive an email, please make sure you've entered the address you registered with, and check your spam folder.


Sebastopol teenager goes missing overnight
Police are appealing for public assistance to help locate missing 13-year-old Sebastian Adams.
Sebastian was last seen at a home in Sebastopol on Wednesday, November 20 (last night) about 6.30pm.
Police and family hold concern for Sebastian due to his age.
He is described as approximately 160cm tall and Caucasian in appearance with an olive complexion, thin build, green eyes and brown hair.

Anyone with information on Sebastian's whereabouts is urged to contact Ballarat Police Station on 03 5336 6000.


Source code for torch.package.package_importer
import builtins
from contextlib import contextmanager
import importlib
import inspect
import io
import linecache
import os.path
import types
from pathlib import Path
from typing import Any, BinaryIO, Callable, Dict, List, Optional, Union
from weakref import WeakValueDictionary
import torch
from torch.serialization import _get_restore_location, _maybe_decode_ascii
from .file_structure_representation import Directory, _create_directory_from_file_list
from .glob_group import GlobPattern
from ._importlib import (
_calc___package__,
_normalize_line_endings,
_normalize_path,
_resolve_name,
_sanity_check,
)
from ._mangling import PackageMangler, demangle
from ._mock_zipreader import MockZipReader
from ._package_unpickler import PackageUnpickler
from .importer import Importer
[docs]class PackageImporter(Importer):
"""Importers allow you to load code written to packages by :class:`PackageExporter`.
Code is loaded in a hermetic way, using files from the package
rather than the normal python import system. This allows
for the packaging of PyTorch model code and data so that it can be run
on a server or used in the future for transfer learning.
The importer for packages ensures that code in the module can only be loaded from
within the package, except for modules explicitly listed as external during export.
The file ``extern_modules`` in the zip archive lists all the modules that a package externally depends on.
This prevents "implicit" dependencies where the package runs locally because it is importing
a locally-installed package, but then fails when the package is copied to another machine.
"""
"""The dictionary of already loaded modules from this package, equivalent to ``sys.modules`` but
local to this importer.
"""
modules: Dict[str, types.ModuleType]
[docs] def __init__(
self,
file_or_buffer: Union[str, torch._C.PyTorchFileReader, Path, BinaryIO],
module_allowed: Callable[[str], bool] = lambda module_name: True,
):
"""Open ``file_or_buffer`` for importing. This checks that the imported package only requires modules
allowed by ``module_allowed``
Args:
file_or_buffer: a file-like object (has to implement :meth:`read`, :meth:`readline`, :meth:`tell`, and :meth:`seek`),
a string, or an ``os.PathLike`` object containing a filename.
module_allowed (Callable[[str], bool], optional): A method to determine if a externally provided module
should be allowed. Can be used to ensure packages loaded do not depend on modules that the server
does not support. Defaults to allowing anything.
Raises:
ImportError: If the package will use a disallowed module.
"""
self.zip_reader: Any
if isinstance(file_or_buffer, torch._C.PyTorchFileReader):
self.filename = "<pytorch_file_reader>"
self.zip_reader = file_or_buffer
elif isinstance(file_or_buffer, (Path, str)):
self.filename = str(file_or_buffer)
if not os.path.isdir(self.filename):
self.zip_reader = torch._C.PyTorchFileReader(self.filename)
else:
self.zip_reader = MockZipReader(self.filename)
else:
self.filename = "<binary>"
self.zip_reader = torch._C.PyTorchFileReader(file_or_buffer)
self.root = _PackageNode(None)
self.modules = {}
self.extern_modules = self._read_extern()
for extern_module in self.extern_modules:
if not module_allowed(extern_module):
raise ImportError(
f"package '{file_or_buffer}' needs the external module '{extern_module}' "
f"but that module has been disallowed"
)
self._add_extern(extern_module)
for fname in self.zip_reader.get_all_records():
self._add_file(fname)
self.patched_builtins = builtins.__dict__.copy()
self.patched_builtins["__import__"] = self.__import__
# Allow packaged modules to reference their PackageImporter
self.modules["torch_package_importer"] = self # type: ignore[assignment]
self._mangler = PackageMangler()
# used for reduce deserializaiton
self.storage_context: Any = None
self.last_map_location = None
# used for torch.serialization._load
self.Unpickler = lambda *args, **kwargs: PackageUnpickler(self, *args, **kwargs)
[docs] def import_module(self, name: str, package=None):
"""Load a module from the package if it hasn't already been loaded, and then return
the module. Modules are loaded locally
to the importer and will appear in ``self.modules`` rather than ``sys.modules``.
Args:
name (str): Fully qualified name of the module to load.
package ([type], optional): Unused, but present to match the signature of importlib.import_module. Defaults to ``None``.
Returns:
types.ModuleType: The (possibly already) loaded module.
"""
return self._gcd_import(name)
[docs] def load_binary(self, package: str, resource: str) -> bytes:
"""Load raw bytes.
Args:
package (str): The name of module package (e.g. ``"my_package.my_subpackage"``).
resource (str): The unique name for the resource.
Returns:
bytes: The loaded data.
"""
path = self._zipfile_path(package, resource)
return self.zip_reader.get_record(path)
[docs] def load_text(
self,
package: str,
resource: str,
encoding: str = "utf-8",
errors: str = "strict",
) -> str:
"""Load a string.
Args:
package (str): The name of module package (e.g. ``"my_package.my_subpackage"``).
resource (str): The unique name for the resource.
encoding (str, optional): Passed to ``decode``. Defaults to ``'utf-8'``.
errors (str, optional): Passed to ``decode``. Defaults to ``'strict'``.
Returns:
str: The loaded text.
"""
data = self.load_binary(package, resource)
return data.decode(encoding, errors)
[docs] def load_pickle(self, package: str, resource: str, map_location=None) -> Any:
"""Unpickles the resource from the package, loading any modules that are needed to construct the objects
using :meth:`import_module`.
Args:
package (str): The name of module package (e.g. ``"my_package.my_subpackage"``).
resource (str): The unique name for the resource.
map_location: Passed to `torch.load` to determine how tensors are mapped to devices. Defaults to ``None``.
Returns:
Any: The unpickled object.
"""
pickle_file = self._zipfile_path(package, resource)
restore_location = _get_restore_location(map_location)
loaded_storages = {}
loaded_reduces = {}
storage_context = torch._C.StorageContext()
def load_tensor(data_type, size, key, location, restore_location):
name = f"{key}.storage"
dtype = data_type(0).dtype
if storage_context.has_storage(name):
storage = storage_context.get_storage(name, dtype).storage()
else:
tensor = self.zip_reader.get_storage_from_record(
".data/" + name, size, dtype
)
if isinstance(self.zip_reader, torch._C.PyTorchFileReader):
storage_context.add_storage(name, tensor)
storage = tensor.storage()
loaded_storages[key] = restore_location(storage, location)
def persistent_load(saved_id):
assert isinstance(saved_id, tuple)
typename = _maybe_decode_ascii(saved_id[0])
data = saved_id[1:]
if typename == "storage":
data_type, key, location, size = data
if key not in loaded_storages:
load_tensor(
data_type,
size,
key,
_maybe_decode_ascii(location),
restore_location,
)
storage = loaded_storages[key]
return storage
elif typename == "reduce_package":
reduce_id, func, args = data
if reduce_id not in loaded_reduces:
loaded_reduces[reduce_id] = func(self, *args)
return loaded_reduces[reduce_id]
else:
f"Unknown typename for persistent_load, expected 'storage' or 'reduce_package' but got '{typename}'"
# Load the data (which may in turn use `persistent_load` to load tensors)
data_file = io.BytesIO(self.zip_reader.get_record(pickle_file))
unpickler = self.Unpickler(data_file)
unpickler.persistent_load = persistent_load
@contextmanager
def set_deserialization_context():
# to let reduce_package access deserializaiton context
self.storage_context = storage_context
self.last_map_location = map_location
try:
yield
finally:
self.storage_context = None
self.last_map_location = None
with set_deserialization_context():
result = unpickler.load()
# TODO from zdevito:
# This stateful weird function will need to be removed in our efforts
# to unify the format. It has a race condition if multiple python
# threads try to read independent files
torch._utils._validate_loaded_sparse_tensors()
return result
[docs] def id(self):
"""
Returns internal identifier that torch.package uses to distinguish :class:`PackageImporter` instances.
Looks like::
<torch_package_0>
"""
return self._mangler.parent_name()
[docs] def file_structure(
self, *, include: "GlobPattern" = "**", exclude: "GlobPattern" = ()
) -> Directory:
"""Returns a file structure representation of package's zipfile.
Args:
include (Union[List[str], str]): An optional string e.g. ``"my_package.my_subpackage"``, or optional list of strings
for the names of the files to be inluded in the zipfile representation. This can also be
a glob-style pattern, as described in :meth:`PackageExporter.mock`
exclude (Union[List[str], str]): An optional pattern that excludes files whose name match the pattern.
Returns:
:class:`Directory`
"""
return _create_directory_from_file_list(
self.filename, self.zip_reader.get_all_records(), include, exclude
)
def _read_extern(self):
return (
self.zip_reader.get_record(".data/extern_modules")
.decode("utf-8")
.splitlines(keepends=False)
)
def _make_module(
self, name: str, filename: Optional[str], is_package: bool, parent: str
):
mangled_filename = self._mangler.mangle(filename) if filename else None
spec = importlib.machinery.ModuleSpec(name, self, is_package=is_package) # type: ignore[arg-type]
module = importlib.util.module_from_spec(spec)
self.modules[name] = module
module.__name__ = self._mangler.mangle(name)
ns = module.__dict__
ns["__spec__"] = spec
ns["__loader__"] = self
ns["__file__"] = mangled_filename
ns["__cached__"] = None
ns["__builtins__"] = self.patched_builtins
ns["__torch_package__"] = True
# Add this module to our private global registry. It should be unique due to mangling.
assert module.__name__ not in _package_imported_modules
_package_imported_modules[module.__name__] = module
# pre-emptively install on the parent to prevent IMPORT_FROM from trying to
# access sys.modules
self._install_on_parent(parent, name, module)
if filename is not None:
assert mangled_filename is not None
# pre-emptively install the source in `linecache` so that stack traces,
# `inspect`, etc. work.
assert filename not in linecache.cache # type: ignore[attr-defined]
linecache.lazycache(mangled_filename, ns)
code = self._compile_source(filename, mangled_filename)
exec(code, ns)
return module
def _load_module(self, name: str, parent: str):
cur: _PathNode = self.root
for atom in name.split("."):
if not isinstance(cur, _PackageNode) or atom not in cur.children:
raise ModuleNotFoundError(
f'No module named "{name}" in self-contained archive "{self.filename}"'
f" and the module is also not in the list of allowed external modules: {self.extern_modules}",
name=name,
)
cur = cur.children[atom]
if isinstance(cur, _ExternNode):
module = self.modules[name] = importlib.import_module(name)
return module
return self._make_module(name, cur.source_file, isinstance(cur, _PackageNode), parent) # type: ignore[attr-defined]
def _compile_source(self, fullpath: str, mangled_filename: str):
source = self.zip_reader.get_record(fullpath)
source = _normalize_line_endings(source)
return compile(source, mangled_filename, "exec", dont_inherit=True)
# note: named `get_source` so that linecache can find the source
# when this is the __loader__ of a module.
def get_source(self, module_name) -> str:
# linecache calls `get_source` with the `module.__name__` as the argument, so we must demangle it here.
module = self.import_module(demangle(module_name))
return self.zip_reader.get_record(demangle(module.__file__)).decode("utf-8")
# note: named `get_resource_reader` so that importlib.resources can find it.
# This is otherwise considered an internal method.
def get_resource_reader(self, fullname):
try:
package = self._get_package(fullname)
except ImportError:
return None
if package.__loader__ is not self:
return None
return _PackageResourceReader(self, fullname)
def _install_on_parent(self, parent: str, name: str, module: types.ModuleType):
if not parent:
return
# Set the module as an attribute on its parent.
parent_module = self.modules[parent]
if parent_module.__loader__ is self: # type: ignore[union-attr]
setattr(parent_module, name.rpartition(".")[2], module)
# note: copied from cpython's import code, with call to create module replaced with _make_module
def _do_find_and_load(self, name):
path = None
parent = name.rpartition(".")[0]
if parent:
if parent not in self.modules:
self._gcd_import(parent)
# Crazy side-effects!
if name in self.modules:
return self.modules[name]
parent_module = self.modules[parent]
try:
path = parent_module.__path__ # type: ignore[attr-defined]
except AttributeError:
msg = (_ERR_MSG + "; {!r} is not a package").format(name, parent)
raise ModuleNotFoundError(msg, name=name) from None
module = self._load_module(name, parent)
self._install_on_parent(parent, name, module)
return module
# note: copied from cpython's import code
def _find_and_load(self, name):
module = self.modules.get(name, _NEEDS_LOADING)
if module is _NEEDS_LOADING:
return self._do_find_and_load(name)
if module is None:
message = "import of {} halted; " "None in sys.modules".format(name)
raise ModuleNotFoundError(message, name=name)
return module
def _gcd_import(self, name, package=None, level=0):
"""Import and return the module based on its name, the package the call is
being made from, and the level adjustment.
This function represents the greatest common denominator of functionality
between import_module and __import__. This includes setting __package__ if
the loader did not.
"""
_sanity_check(name, package, level)
if level > 0:
name = _resolve_name(name, package, level)
return self._find_and_load(name)
# note: copied from cpython's import code
def _handle_fromlist(self, module, fromlist, *, recursive=False):
"""Figure out what __import__ should return.
The import_ parameter is a callable which takes the name of module to
import. It is required to decouple the function from assuming importlib's
import implementation is desired.
"""
module_name = demangle(module.__name__)
# The hell that is fromlist ...
# If a package was imported, try to import stuff from fromlist.
if hasattr(module, "__path__"):
for x in fromlist:
if not isinstance(x, str):
if recursive:
where = module_name + ".__all__"
else:
where = "``from list''"
raise TypeError(
f"Item in {where} must be str, " f"not {type(x).__name__}"
)
elif x == "*":
if not recursive and hasattr(module, "__all__"):
self._handle_fromlist(module, module.__all__, recursive=True)
elif not hasattr(module, x):
from_name = "{}.{}".format(module_name, x)
try:
self._gcd_import(from_name)
except ModuleNotFoundError as exc:
# Backwards-compatibility dictates we ignore failed
# imports triggered by fromlist for modules that don't
# exist.
if (
exc.name == from_name
and self.modules.get(from_name, _NEEDS_LOADING) is not None
):
continue
raise
return module
def __import__(self, name, globals=None, locals=None, fromlist=(), level=0):
if level == 0:
module = self._gcd_import(name)
else:
globals_ = globals if globals is not None else {}
package = _calc___package__(globals_)
module = self._gcd_import(name, package, level)
if not fromlist:
# Return up to the first dot in 'name'. This is complicated by the fact
# that 'name' may be relative.
if level == 0:
return self._gcd_import(name.partition(".")[0])
elif not name:
return module
else:
# Figure out where to slice the module's name up to the first dot
# in 'name'.
cut_off = len(name) - len(name.partition(".")[0])
# Slice end needs to be positive to alleviate need to special-case
# when ``'.' not in name``.
module_name = demangle(module.__name__)
return self.modules[module_name[: len(module_name) - cut_off]]
else:
return self._handle_fromlist(module, fromlist)
def _get_package(self, package):
"""Take a package name or module object and return the module.
If a name, the module is imported. If the passed or imported module
object is not a package, raise an exception.
"""
if hasattr(package, "__spec__"):
if package.__spec__.submodule_search_locations is None:
raise TypeError("{!r} is not a package".format(package.__spec__.name))
else:
return package
else:
module = self.import_module(package)
if module.__spec__.submodule_search_locations is None:
raise TypeError("{!r} is not a package".format(package))
else:
return module
def _zipfile_path(self, package, resource=None):
package = self._get_package(package)
assert package.__loader__ is self
name = demangle(package.__name__)
if resource is not None:
resource = _normalize_path(resource)
return f"{name.replace('.', '/')}/{resource}"
else:
return f"{name.replace('.', '/')}"
def _get_or_create_package(
self, atoms: List[str]
) -> "Union[_PackageNode, _ExternNode]":
cur = self.root
for i, atom in enumerate(atoms):
node = cur.children.get(atom, None)
if node is None:
node = cur.children[atom] = _PackageNode(None)
if isinstance(node, _ExternNode):
return node
if isinstance(node, _ModuleNode):
name = ".".join(atoms[:i])
raise ImportError(
f"inconsistent module structure. module {name} is not a package, but has submodules"
)
assert isinstance(node, _PackageNode)
cur = node
return cur
def _add_file(self, filename: str):
"""Assembles a Python module out of the given file. Will ignore files in the .data directory.
Args:
filename (str): the name of the file inside of the package archive to be added
"""
*prefix, last = filename.split("/")
if len(prefix) > 1 and prefix[0] == ".data":
return
package = self._get_or_create_package(prefix)
if isinstance(package, _ExternNode):
raise ImportError(
f"inconsistent module structure. package contains a module file {filename}"
f" that is a subpackage of a module marked external."
)
if last == "__init__.py":
package.source_file = filename
elif last.endswith(".py"):
package_name = last[: -len(".py")]
package.children[package_name] = _ModuleNode(filename)
def _add_extern(self, extern_name: str):
*prefix, last = extern_name.split(".")
package = self._get_or_create_package(prefix)
if isinstance(package, _ExternNode):
return # the shorter extern covers this extern case
package.children[last] = _ExternNode()
_NEEDS_LOADING = object()
_ERR_MSG_PREFIX = "No module named "
_ERR_MSG = _ERR_MSG_PREFIX + "{!r}"
class _PathNode:
pass
class _PackageNode(_PathNode):
def __init__(self, source_file: Optional[str]):
self.source_file = source_file
self.children: Dict[str, _PathNode] = {}
class _ModuleNode(_PathNode):
__slots__ = ["source_file"]
def __init__(self, source_file: str):
self.source_file = source_file
class _ExternNode(_PathNode):
pass
# A private global registry of all modules that have been package-imported.
_package_imported_modules: WeakValueDictionary = WeakValueDictionary()
# `inspect` by default only looks in `sys.modules` to find source files for classes.
# Patch it to check our private registry of package-imported modules as well.
_orig_getfile = inspect.getfile
def patched_getfile(object):
if inspect.isclass(object):
if object.__module__ in _package_imported_modules:
return _package_imported_modules[object.__module__].__file__
return _orig_getfile(object)
inspect.getfile = patched_getfile
class _PackageResourceReader:
"""Private class used to support PackageImporter.get_resource_reader().
Confirms to the importlib.abc.ResourceReader interface. Allowed to access
the innards of PackageImporter.
"""
def __init__(self, importer, fullname):
self.importer = importer
self.fullname = fullname
def open_resource(self, resource):
from io import BytesIO
return BytesIO(self.importer.load_binary(self.fullname, resource))
def resource_path(self, resource):
# The contract for resource_path is that it either returns a concrete
# file system path or raises FileNotFoundError.
raise FileNotFoundError
def is_resource(self, name):
path = self.importer._zipfile_path(self.fullname, name)
return self.importer.zip_reader.has_record(path)
def contents(self):
from pathlib import Path
filename = self.fullname.replace(".", "/")
fullname_path = Path(self.importer._zipfile_path(self.fullname))
files = self.importer.zip_reader.get_all_records()
subdirs_seen = set()
for filename in files:
try:
relative = Path(filename).relative_to(fullname_path)
except ValueError:
continue
# If the path of the file (which is relative to the top of the zip
# namespace), relative to the package given when the resource
# reader was created, has a parent, then it's a name in a
# subdirectory and thus we skip it.
parent_name = relative.parent.name
if len(parent_name) == 0:
yield relative.name
elif parent_name not in subdirs_seen:
subdirs_seen.add(parent_name)
yield parent_name


With NOMAD you get an accurate goal o follow as well as a chance for your computer to plan the best trip for you based on your budget.
Plan your Travel
Save for your trip
London tour
1 week tripExplore the Egyptian Pyramids
2 weeksGet to know Germany
3 weeksThe Luxury trip offers a one of a kind vacation. The Grand Trip provides amazing opportunities to get to know a place. The Economic Trip consists of the basic vacation. The Cheap Trip tries to save you the most amount of money while still providing you with an experience. These experiences are chosen based on your budget.
Not only will you keep a track of your goal, but also gain unique insights into your trip in order to give you the best experience based on YOUR price.
Enjoy a luxurious vacation in the French coast. With a budget of 13,000$ you can explore the French paradise and enjoy the beautiful weather and calming waters in what is truly an european paradise.


our vision was to create a website that will transform our individual pictures and our favorit song into a music video.
in the modern world we like watching video music in work event, birthday, anniversaries etcetera to remember happy moments, however creating the video is time consuming and can be tedious.
so we did all the hard work for you! all you need to do is to upoad your images, your favorit song and in seconds you will get your music video! shall we start?
computer science student in Tel Hai college.
computer science student in Tel Hai college.
computer science lecturer in Tel Hai college.
doing the best we can in order to ensure easy use for the client, with build in steps to crseate the best music video.
studied well all the back scene code needed to ensure fast result, we wouldn't like you to wait long for your video/
we are motivated to improve our website and add more features in ordr to improve the outcome music video, so that life before our website will be seen weird.
we are not yet expert in web programing, Howevre we hope that in the future we will be able to say we are.


SUBROUTINE ZPTCON( N, D, E, ANORM, RCOND, RWORK, INFO ) * * -- LAPACK routine (version 3.1) -- * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. * November 2006 * * .. Scalar Arguments .. INTEGER INFO, N DOUBLE PRECISION ANORM, RCOND * .. * .. Array Arguments .. DOUBLE PRECISION D( * ), RWORK( * ) COMPLEX*16 E( * ) * .. * * Purpose * ======= * * ZPTCON computes the reciprocal of the condition number (in the * 1-norm) of a complex Hermitian positive definite tridiagonal matrix * using the factorization A = L*D*L**H or A = U**H*D*U computed by * ZPTTRF. * * Norm(inv(A)) is computed by a direct method, and the reciprocal of * the condition number is computed as * RCOND = 1 / (ANORM * norm(inv(A))). * * Arguments * ========= * * N (input) INTEGER * The order of the matrix A. N >= 0. * * D (input) DOUBLE PRECISION array, dimension (N) * The n diagonal elements of the diagonal matrix D from the * factorization of A, as computed by ZPTTRF. * * E (input) COMPLEX*16 array, dimension (N-1) * The (n-1) off-diagonal elements of the unit bidiagonal factor * U or L from the factorization of A, as computed by ZPTTRF. * * ANORM (input) DOUBLE PRECISION * The 1-norm of the original matrix A. * * RCOND (output) DOUBLE PRECISION * The reciprocal of the condition number of the matrix A, * computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is the * 1-norm of inv(A) computed in this routine. * * RWORK (workspace) DOUBLE PRECISION array, dimension (N) * * INFO (output) INTEGER * = 0: successful exit * < 0: if INFO = -i, the i-th argument had an illegal value * * Further Details * =============== * * The method used is described in Nicholas J. Higham, "Efficient * Algorithms for Computing the Condition Number of a Tridiagonal * Matrix", SIAM J. Sci. Stat. Comput., Vol. 7, No. 1, January 1986. * * ===================================================================== * * .. Parameters .. DOUBLE PRECISION ONE, ZERO PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) * .. * .. Local Scalars .. INTEGER I, IX DOUBLE PRECISION AINVNM * .. * .. External Functions .. INTEGER IDAMAX EXTERNAL IDAMAX * .. * .. External Subroutines .. EXTERNAL XERBLA * .. * .. Intrinsic Functions .. INTRINSIC ABS * .. * .. Executable Statements .. * * Test the input arguments. * INFO = 0 IF( N.LT.0 ) THEN INFO = -1 ELSE IF( ANORM.LT.ZERO ) THEN INFO = -4 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'ZPTCON', -INFO ) RETURN END IF * * Quick return if possible * RCOND = ZERO IF( N.EQ.0 ) THEN RCOND = ONE RETURN ELSE IF( ANORM.EQ.ZERO ) THEN RETURN END IF * * Check that D(1:N) is positive. * DO 10 I = 1, N IF( D( I ).LE.ZERO ) $ RETURN 10 CONTINUE * * Solve M(A) * x = e, where M(A) = (m(i,j)) is given by * * m(i,j) = abs(A(i,j)), i = j, * m(i,j) = -abs(A(i,j)), i .ne. j, * * and e = [ 1, 1, ..., 1 ]'. Note M(A) = M(L)*D*M(L)'. * * Solve M(L) * x = e. * RWORK( 1 ) = ONE DO 20 I = 2, N RWORK( I ) = ONE + RWORK( I-1 )*ABS( E( I-1 ) ) 20 CONTINUE * * Solve D * M(L)' * x = b. * RWORK( N ) = RWORK( N ) / D( N ) DO 30 I = N - 1, 1, -1 RWORK( I ) = RWORK( I ) / D( I ) + RWORK( I+1 )*ABS( E( I ) ) 30 CONTINUE * * Compute AINVNM = max(x(i)), 1<=i<=n. * IX = IDAMAX( N, RWORK, 1 ) AINVNM = ABS( RWORK( IX ) ) * * Compute the reciprocal condition number. * IF( AINVNM.NE.ZERO ) $ RCOND = ( ONE / AINVNM ) / ANORM * RETURN * * End of ZPTCON * END


UX Design Projects
Marketplace for Motoroso.com
Three week client project to design a marketplace for Motoroso.com
Recommendation App for Scholastic
Two week class project to create an app to increase reading engagement in children ages 8-12.
Ecommerce Website for True Spirit
Two week class project to create an ecommerce website.
Extras
About
Short bio.
Contact
Drop me an email.
Other
Other side projects I've done for fun.


3
Qualifications for Overseers
1 The saying is trustworthy: If anyone aspires to the office of overseer, he desires a noble task.
2 Therefore an overseer must be above reproach, the husband of one wife, sober-minded, self-controlled, respectable, hospitable, able to teach,
3 not a drunkard, not violent but gentle, not quarrelsome, not a lover of money.
4 He must manage his own household well, with all dignity keeping his children submissive,
5 for if someone does not know how to manage his own household, how will he care for God's church?
6 He must not be a recent convert, or he may become puffed up with conceit and fall into the condemnation of the devil.
7 Moreover, he must be well thought of by outsiders, so that he may not fall into disgrace, into a snare of the devil.
Qualifications for Deacons
8 Deacons likewise must be dignified, not double-tongued, not addicted to much wine, not greedy for dishonest gain.
9 They must hold the mystery of the faith with a clear conscience.
10 And let them also be tested first; then let them serve as deacons if they prove themselves blameless.
11 Their wives likewise must be dignified, not slanderers, but sober-minded, faithful in all things.
12 Let deacons each be the husband of one wife, managing their children and their own households well.
13 For those who serve well as deacons gain a good standing for themselves and also great confidence in the faith that is in Christ Jesus.
The Mystery of Godliness
14 I hope to come to you soon, but I am writing these things to you so that,
15 if I delay, you may know how one ought to behave in the household of God, which is the church of the living God, a pillar and buttress of truth.
16 Great indeed, we confess, is the mystery of godliness:
He was manifested in the flesh,
vindicated by the Spirit, seen by angels,
proclaimed among the nations,
believed on in the world, taken up in glory.


Enter Trip Info
Location Name
Description
Device Location
Latitude:
Longitude:
Altitude:
Save Trip
See data


The HAR Viewer application can be found at /webapp/.
The browser-based unit tests can be found at /node_modules/intern/.
The resources for the functional tests can be found in the /selenium/ folder, but this is not browseable.


Crowthereum | Projects list
Loading... (Maybe log in to MetaMask and refresh that page)
Create You Own Project
Create new project
Completed Projects:
Project content goes here...
Projects to Invest:
Project content goes here...
Expired Projects:
Project content goes here...


Black Friday PS4 deals may not be great right now, but they will improve
by Vic HoodBlack Friday PS4 deals may not be great right now, but they will improve
Here's why
(Image credit: Shutterstock)
When it comes to Black Friday PS4 and PS4 Pro deals, it looks like the best deals are coming to US retailers. But have no fear, we're expecting better offers on the way.
Already we've seen Sony reveal its official PlayStation Black Friday deals over the water but, according the the PlayStation UK Black Friday page, we can expect "incredible Black Friday deals". Although, they haven't been revealed yet.
We can, however, expect essentially the same deals as our US friends got, which means we'll see offers on top Sony exclusives, PS4 bundles, PS Plus membership and PSVR bundles. We're just not exactly sure when they'll be revealed.
- Why you might not want to buy a PS4 this Black Friday
- These are the best PS4 Black Friday deals we saw last year
- Why Black Friday is the best time to renew your PS Plus membership
But what about other retailers outside of Sony itself? We're seeing some PS4 deals trickling out from the likes of Currys and Amazon, but we're expecting the best deals to roll out over this week and, obviously, during Black Friday and Cyber Monday.
This was the case last Black Friday, and we definitely weren't disappointed with offers on great PS4 bundles and titles such as Red Dead Redemption 2 and Marvel's Spider-Man. So hang in there!
In the meantime, we've popped some of the best PS4 deals we're seeing ahead of Black Friday below for your perusal:
From October 25, pick up the Sony Xperia 1, Xperia 5, Xperia 10 or Xperia L3 at Carphone Warehouse and bag yourself a free 500GB PS4 and copy of Call of Duty: Modern Warfare - freebies worth £249.99! While stocks last.
View Deal
Once those official PlayStation deals go live, we'll let you know, so keep your eye on TechRadar.
TechRadar is scouring every retailer and rounding up all the top deals over the Black Friday period, and we’ve put all the best Black Friday deals and Cyber Monday deals in easy-to-navigate articles to help you find the bargains you’re looking for.
- These are the best PS4 games right now


Exploring time series for signal detection. It is specifically designed to detect possible outbreaks using infectious disease surveillance data at the European Union / European Economic Area or country level. Automatic detection tools used are presented in the paper "Monitoring count time series in R: aberration detection in public health surveillance", by Salmon et al. (2016) <doi:10.18637/jss.v070.i10>. The package includes: - Signal Detection tool, an interactive 'shiny' application in which the user can import external data and perform basic signal detection analyses; - An automated report in HTML format, presenting the results of the time series analysis in tables and graphs. This report can also be stratified by population characteristics (see 'Population' variable). This project was funded by the European Centre for Disease Prevention and Control.
| Version: | 0.1.1 |
| Depends: | R (≥ 3.4.0) |
| Imports: | shiny, dplyr, pander, DT, surveillance, ISOweek, ggplot2, graphics, utils, knitr (≥ 1.20), rmarkdown |
| Published: | 2018-11-15 |
| Author: | Lore Merdrignac [aut, ctr] (Author of the package and original code), Joana Gomes Dias [aut, fnd, cre] (Project manager and package maintainer), Esther Kissling [aut, ctr], Tommi Karki [aut, fnd], Margot Einoder-Moreno [ctb, fnd] |
| Maintainer: | Joana Gomes Dias <joana.gomes.dias at ecdc.europa.eu> |
| License: | EUPL |
| URL: | http://atlas.ecdc.europa.eu/public/index.aspx |
| NeedsCompilation: | no |
| Materials: | README NEWS |
| CRAN checks: | EpiSignalDetection results |
| Reference manual: | EpiSignalDetection.pdf |
| Vignettes: |
The 'Epidemiological Signal Detection' Package |
| Package source: | EpiSignalDetection_0.1.1.tar.gz |
| Windows binaries: | r-devel: EpiSignalDetection_0.1.1.zip, r-release: EpiSignalDetection_0.1.1.zip, r-oldrel: EpiSignalDetection_0.1.1.zip |
| OS X binaries: | r-release: not available, r-oldrel: not available |
| Old sources: | EpiSignalDetection archive |
Please use the canonical form https://CRAN.R-project.org/package=EpiSignalDetection to link to this page.