├── .devcontainer ├── Dockerfile ├── devcontainer.json └── library-scripts │ └── common-debian.sh ├── .gitignore ├── .vscode └── settings.json ├── 01_hello ├── AllTest.ps1 ├── README.md ├── hello.ipynb ├── hello.ps1 ├── solution1.ps1 └── test.ps1 ├── 02_crowsnest ├── AllTest.ps1 ├── README.md ├── crowsnest.ipynb ├── crowsnest.ps1 ├── solution1.ps1 └── test.ps1 ├── 03_picnic ├── AllTest.ps1 ├── README.md ├── picnic.ipynb ├── picnic.ps1 ├── solution1.ps1 └── test.ps1 ├── 04_jump_the_five ├── 04_jump_the_five.ps1 ├── AllTest.ps1 ├── README.md ├── jump.ipynb ├── jump.ps1 ├── solution1.ps1 └── test.ps1 ├── 05_howler ├── AllTest.ps1 ├── README.md ├── howler.ipynb ├── howler.ps1 ├── solution1.ps1 └── test.ps1 ├── 06_wc ├── AllTest.ps1 ├── README.md ├── inputs │ ├── empty.txt │ ├── foo.txt │ ├── one.txt │ └── two.txt ├── solution1.ps1 ├── test.ps1 ├── wc.ipynb └── wc.ps1 ├── 07_gashlycrumb ├── AllTest.ps1 ├── Gashlycrumb.ipynb ├── README.md ├── alternate.txt ├── gashlycrumb.ps1 ├── gashlycrumb.txt ├── solution1.ps1 └── test.ps1 ├── 08_apples_and_bananas ├── AllTest.ps1 ├── README.md ├── apples.ipynb ├── apples.ps1 ├── solution1.ps1 └── test.ps1 ├── 09_abuse ├── AllTest.ps1 ├── README.md ├── abuse.ipynb ├── abuse.ps1 ├── solution1.ps1 └── test.ps1 ├── 10_telephone ├── AllTest.ps1 ├── README.md ├── solution1.ps1 ├── telephone.ipynb ├── telephone.ps1 └── test.ps1 ├── 11_bottles_of_beer ├── AllTest.ps1 ├── README.md ├── bottles.ipynb ├── bottles.ps1 ├── solution1.ps1 └── test.ps1 ├── 12_ransom ├── AllTest.ps1 ├── README.md ├── ransom.ipynb ├── ransom.ps1 ├── solution1.ps1 └── test.ps1 ├── 13_twelve_days ├── AllTest.ps1 ├── README.md ├── solution1.ps1 ├── test.ps1 ├── twelve_days.ipynb └── twelve_days.ps1 ├── 14_rhymer ├── AllTest.ps1 ├── README.md ├── rhymer.ipynb ├── rhymer.ps1 ├── solution1.ps1 └── test.ps1 ├── 15_kentucky_friar ├── AllTest.ps1 ├── README.md ├── friar.ipynb ├── friar.ps1 ├── inputs │ ├── banner.txt │ ├── blake.txt │ ├── dickinson.txt │ ├── raven.txt │ └── shakespeare.txt ├── solution1.ps1 └── test.ps1 ├── 16_scrambler ├── AllTest.ps1 ├── README.md ├── scrambler.ipynb ├── scrambler.ps1 ├── solution1.ps1 └── test.ps1 ├── 17_mad_libs ├── AllTest.ps1 ├── README.md ├── inputs │ └── fox.txt ├── mad.ipynb ├── mad.ps1 ├── solution1.ps1 └── test.ps1 ├── 18_gematria ├── AllTest.ps1 ├── README.md ├── gematria.ipynb ├── gematria.ps1 ├── solution1.ps1 ├── solution2-foreach-pipe.ps1 └── test.ps1 ├── 19_wod ├── 19_wod.ps1 ├── AllTest.ps1 ├── README.md ├── inputs │ ├── bad-delimiter.tab │ ├── bad-empty.csv │ ├── bad-headers-only.csv │ ├── bad-headers.csv │ ├── bad-reps.csv │ ├── exercises.csv │ └── silly-exercises.csv ├── solution1.ps1 ├── test.ps1 ├── wod.ipynb └── wod.ps1 ├── 20_password ├── AllTest.ps1 ├── README.md ├── const │ ├── adjs.txt │ ├── nouns.txt │ └── verbs.txt ├── password.ipynb ├── password.ps1 ├── scarlet │ ├── adjs.txt │ ├── nouns.txt │ └── verbs.txt ├── solution1.ps1 ├── sonnets │ ├── adjs.txt │ ├── nouns.txt │ └── verbs.txt └── test.ps1 ├── 21_tictactoe ├── AllTest.ps1 ├── README.md ├── solution1.ps1 ├── test.ps1 └── tictactoe.ps1 ├── 22_itictactoe ├── AllTest.ps1 ├── README.md ├── itictactoe.ps1 └── test.ps1 ├── Dockerfile ├── LICENSE ├── NuGet.config ├── README.md ├── RunAllTests.ps1 ├── UtilityModules └── UtilityModules.psm1 └── inputFiles ├── const.txt ├── dickinson.txt ├── fox.txt ├── gettysburg.txt ├── issa.txt ├── nobody.txt ├── now.txt ├── out.txt ├── preamble.txt ├── scarlet.txt ├── sonnet-29.txt ├── sonnets.txt ├── spiders.txt ├── the-bustle.txt ├── usdeclar.txt └── words.txt /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/powershell:lts-debian-10 2 | 3 | # [Option] Install zsh 4 | ARG INSTALL_ZSH="true" 5 | # [Option] Upgrade OS packages to their latest versions 6 | ARG UPGRADE_PACKAGES="false" 7 | 8 | # Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies. 9 | ARG USERNAME=vscode 10 | ARG USER_UID=1000 11 | ARG USER_GID=$USER_UID 12 | COPY library-scripts/*.sh /tmp/library-scripts/ 13 | RUN apt-get update \ 14 | && /bin/bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" \ 15 | && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts 16 | 17 | # [Optional] Uncomment this section to install additional packages. 18 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 19 | # && apt-get -y install --no-install-recommends 20 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.140.1/containers/powershell 3 | { 4 | "name": "PowerShell", 5 | "dockerFile": "Dockerfile", 6 | // Set *default* container specific settings.json values on container create. 7 | "settings": { 8 | "terminal.integrated.shell.linux": "/usr/bin/pwsh" 9 | }, 10 | // Add the IDs of extensions you want installed when the container is created. 11 | "extensions": [ 12 | "ms-vscode.powershell" 13 | ], 14 | "build": { 15 | "args": { 16 | "INSTALL_ZSH": "false" 17 | } 18 | }, 19 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 20 | // "forwardPorts": [], 21 | // Uncomment the next line to run commands after the container is created. This gets run in bash which is why we call `pwsh`. 22 | "postCreateCommand": "pwsh -c 'install-module pester -force'" 23 | 24 | // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. 25 | // "remoteUser": "vscode" 26 | } -------------------------------------------------------------------------------- /.devcontainer/library-scripts/common-debian.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #------------------------------------------------------------------------------------------------------------- 3 | # Copyright (c) Microsoft Corporation. All rights reserved. 4 | # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. 5 | #------------------------------------------------------------------------------------------------------------- 6 | 7 | # Syntax: ./common-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag] 8 | 9 | INSTALL_ZSH=${1:-"true"} 10 | USERNAME=${2:-"vscode"} 11 | USER_UID=${3:-1000} 12 | USER_GID=${4:-1000} 13 | UPGRADE_PACKAGES=${5:-"true"} 14 | 15 | set -e 16 | 17 | if [ "$(id -u)" -ne 0 ]; then 18 | echo -e 'Script must be run a root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 19 | exit 1 20 | fi 21 | 22 | # Treat a user name of "none" as root 23 | if [ "${USERNAME}" = "none" ] || [ "${USERNAME}" = "root" ]; then 24 | USERNAME=root 25 | USER_UID=0 26 | USER_GID=0 27 | fi 28 | 29 | # Load markers to see which steps have already run 30 | MARKER_FILE="/usr/local/etc/vscode-dev-containers/common" 31 | if [ -f "${MARKER_FILE}" ]; then 32 | echo "Marker file found:" 33 | cat "${MARKER_FILE}" 34 | source "${MARKER_FILE}" 35 | fi 36 | 37 | # Ensure apt is in non-interactive to avoid prompts 38 | export DEBIAN_FRONTEND=noninteractive 39 | 40 | # Function to call apt-get if needed 41 | apt-get-update-if-needed() 42 | { 43 | if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then 44 | echo "Running apt-get update..." 45 | apt-get update 46 | else 47 | echo "Skipping apt-get update." 48 | fi 49 | } 50 | 51 | # Run install apt-utils to avoid debconf warning then verify presence of other common developer tools and dependencies 52 | if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then 53 | apt-get-update-if-needed 54 | 55 | PACKAGE_LIST="apt-utils \ 56 | git \ 57 | openssh-client \ 58 | gnupg2 \ 59 | iproute2 \ 60 | procps \ 61 | lsof \ 62 | htop \ 63 | net-tools \ 64 | psmisc \ 65 | curl \ 66 | wget \ 67 | rsync \ 68 | ca-certificates \ 69 | unzip \ 70 | zip \ 71 | nano \ 72 | vim-tiny \ 73 | less \ 74 | jq \ 75 | lsb-release \ 76 | apt-transport-https \ 77 | dialog \ 78 | libc6 \ 79 | libgcc1 \ 80 | libgssapi-krb5-2 \ 81 | libicu[0-9][0-9] \ 82 | liblttng-ust0 \ 83 | libstdc++6 \ 84 | zlib1g \ 85 | locales \ 86 | sudo \ 87 | ncdu \ 88 | man-db" 89 | 90 | # Install libssl1.1 if available 91 | if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then 92 | PACKAGE_LIST="${PACKAGE_LIST} libssl1.1" 93 | fi 94 | 95 | # Install appropriate version of libssl1.0.x if available 96 | LIBSSL=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '') 97 | if [ "$(echo "$LIBSSL" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then 98 | if [[ ! -z $(apt-cache --names-only search ^libssl1.0.2$) ]]; then 99 | # Debian 9 100 | PACKAGE_LIST="${PACKAGE_LIST} libssl1.0.2" 101 | elif [[ ! -z $(apt-cache --names-only search ^libssl1.0.0$) ]]; then 102 | # Ubuntu 18.04, 16.04, earlier 103 | PACKAGE_LIST="${PACKAGE_LIST} libssl1.0.0" 104 | fi 105 | fi 106 | 107 | echo "Packages to verify are installed: ${PACKAGE_LIST}" 108 | apt-get -y install --no-install-recommends ${PACKAGE_LIST} 2> >( grep -v 'debconf: delaying package configuration, since apt-utils is not installed' >&2 ) 109 | 110 | PACKAGES_ALREADY_INSTALLED="true" 111 | fi 112 | 113 | # Get to latest versions of all packages 114 | if [ "${UPGRADE_PACKAGES}" = "true" ]; then 115 | apt-get-update-if-needed 116 | apt-get -y upgrade --no-install-recommends 117 | apt-get autoremove -y 118 | fi 119 | 120 | # Ensure at least the en_US.UTF-8 UTF-8 locale is available. 121 | # Common need for both applications and things like the agnoster ZSH theme. 122 | if [ "${LOCALE_ALREADY_SET}" != "true" ]; then 123 | echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen 124 | locale-gen 125 | LOCALE_ALREADY_SET="true" 126 | fi 127 | 128 | # Create or update a non-root user to match UID/GID - see https://aka.ms/vscode-remote/containers/non-root-user. 129 | if id -u $USERNAME > /dev/null 2>&1; then 130 | # User exists, update if needed 131 | if [ "$USER_GID" != "$(id -G $USERNAME)" ]; then 132 | groupmod --gid $USER_GID $USERNAME 133 | usermod --gid $USER_GID $USERNAME 134 | fi 135 | if [ "$USER_UID" != "$(id -u $USERNAME)" ]; then 136 | usermod --uid $USER_UID $USERNAME 137 | fi 138 | else 139 | # Create user 140 | groupadd --gid $USER_GID $USERNAME 141 | useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME 142 | fi 143 | 144 | # Add add sudo support for non-root user 145 | if [ "${USERNAME}" != "root" ] && [ "${EXISTING_NON_ROOT_USER}" != "${USERNAME}" ]; then 146 | echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME 147 | chmod 0440 /etc/sudoers.d/$USERNAME 148 | EXISTING_NON_ROOT_USER="${USERNAME}" 149 | fi 150 | 151 | # .bashrc/.zshrc snippet 152 | RC_SNIPPET="$(cat << EOF 153 | export USER=\$(whoami) 154 | 155 | export PATH=\$PATH:\$HOME/.local/bin 156 | 157 | if [[ \$(which code-insiders 2>&1) && ! \$(which code 2>&1) ]]; then 158 | alias code=code-insiders 159 | fi 160 | EOF 161 | )" 162 | 163 | # Ensure ~/.local/bin is in the PATH for root and non-root users for bash. (zsh is later) 164 | if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then 165 | echo "${RC_SNIPPET}" >> /etc/bash.bashrc 166 | RC_SNIPPET_ALREADY_ADDED="true" 167 | fi 168 | 169 | # Optionally install and configure zsh 170 | if [ "${INSTALL_ZSH}" = "true" ] && [ ! -d "/root/.oh-my-zsh" ] && [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then 171 | apt-get-update-if-needed 172 | apt-get install -y zsh 173 | curl -fsSLo- https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh | bash 2>&1 174 | echo "${RC_SNIPPET}" >> /etc/zsh/zshrc 175 | echo -e "DEFAULT_USER=\$USER\nprompt_context(){}" >> /root/.zshrc 176 | cp -fR /root/.oh-my-zsh /etc/skel 177 | cp -f /root/.zshrc /etc/skel 178 | sed -i -e "s/\/root\/.oh-my-zsh/\/home\/\$(whoami)\/.oh-my-zsh/g" /etc/skel/.zshrc 179 | if [ "${USERNAME}" != "root" ]; then 180 | cp -fR /etc/skel/.oh-my-zsh /etc/skel/.zshrc /home/$USERNAME 181 | chown -R $USER_UID:$USER_GID /home/$USERNAME/.oh-my-zsh /home/$USERNAME/.zshrc 182 | fi 183 | ZSH_ALREADY_INSTALLED="true" 184 | fi 185 | 186 | # Write marker file 187 | mkdir -p "$(dirname "${MARKER_FILE}")" 188 | echo -e "\ 189 | PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED}\n\ 190 | LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET}\n\ 191 | EXISTING_NON_ROOT_USER=${EXISTING_NON_ROOT_USER}\n\ 192 | RC_SNIPPET_ALREADY_ADDED=${RC_SNIPPET_ALREADY_ADDED}\n\ 193 | ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED}" > "${MARKER_FILE}" 194 | 195 | echo "Done!" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | */.ipynb_checkpoints/* 2 | 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "powershell.codeFormatting.addWhitespaceAroundPipe": true 3 | } -------------------------------------------------------------------------------- /01_hello/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/01_hello/AllTest.ps1 -------------------------------------------------------------------------------- /01_hello/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/01_hello/README.md -------------------------------------------------------------------------------- /01_hello/hello.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Hello, World!\n", 8 | "\n", 9 | "Write a program to enthusiastically greet the world." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 9, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "Hello, World!\r\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | ".\\hello.ps1" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "The program should also accept a name given as an optional `-n` parameter" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 10, 49 | "metadata": { 50 | "dotnet_interactive": { 51 | "language": "pwsh" 52 | }, 53 | "polyglot_notebook": { 54 | "kernelName": "pwsh" 55 | }, 56 | "vscode": { 57 | "languageId": "polyglot-notebook" 58 | } 59 | }, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "Hello, Universe!\r\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | ".\\hello.ps1 -n Universe" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "The program should also accept a name given as an optional `-name` parameter" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 11, 83 | "metadata": { 84 | "dotnet_interactive": { 85 | "language": "pwsh" 86 | }, 87 | "polyglot_notebook": { 88 | "kernelName": "pwsh" 89 | }, 90 | "vscode": { 91 | "languageId": "polyglot-notebook" 92 | } 93 | }, 94 | "outputs": [ 95 | { 96 | "name": "stdout", 97 | "output_type": "stream", 98 | "text": [ 99 | "Hello, Multiverse!\r\n" 100 | ] 101 | } 102 | ], 103 | "source": [ 104 | ".\\hello.ps1 -name Multiverse" 105 | ] 106 | } 107 | ], 108 | "metadata": { 109 | "kernelspec": { 110 | "display_name": ".NET (PowerShell)", 111 | "language": "PowerShell", 112 | "name": ".net-powershell" 113 | }, 114 | "language_info": { 115 | "file_extension": ".ps1", 116 | "mimetype": "text/x-powershell", 117 | "name": "PowerShell", 118 | "pygments_lexer": "powershell", 119 | "version": "7.0" 120 | } 121 | }, 122 | "nbformat": 4, 123 | "nbformat_minor": 4 124 | } 125 | -------------------------------------------------------------------------------- /01_hello/hello.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $name = "World" 18 | ) 19 | 20 | 'Hello, ' + $name + '!' 21 | -------------------------------------------------------------------------------- /01_hello/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $name = "World" 18 | ) 19 | 20 | 'Hello, ' + $name + '!' 21 | -------------------------------------------------------------------------------- /01_hello/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/01_hello/test.ps1 -------------------------------------------------------------------------------- /02_crowsnest/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/02_crowsnest/AllTest.ps1 -------------------------------------------------------------------------------- /02_crowsnest/README.md: -------------------------------------------------------------------------------- 1 | # Crow's Nest 2 | 3 | Write a program that will announce the appearance of something "off the larboard bow" to the captain of the ship. 4 | 5 | Note that you need to "a" before a word starting with a consonant. 6 | 7 | ``` 8 | C:\PS> ./crowsnest.ps1 narwhal 9 | Ahoy, Captain, a narwhal off the larboard bow! 10 | ``` 11 | 12 | Or "an" before a word starting with a vowel: 13 | 14 | ``` 15 | C:\PS> ./crowsnest.ps1 octopus 16 | Ahoy, Captain, an octopus off the larboard bow! 17 | ``` 18 | -------------------------------------------------------------------------------- /02_crowsnest/crowsnest.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Crow's Nest\n", 8 | "\n", 9 | "Write a program that will announce the appearance of something \"off the larboard bow\" to the captain of the ship." 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "Note that you need to \"a\" before a word starting with a consonant" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": { 23 | "dotnet_interactive": { 24 | "language": "pwsh" 25 | }, 26 | "polyglot_notebook": { 27 | "kernelName": "pwsh" 28 | }, 29 | "vscode": { 30 | "languageId": "polyglot-notebook" 31 | } 32 | }, 33 | "outputs": [ 34 | { 35 | "name": "stdout", 36 | "output_type": "stream", 37 | "text": [ 38 | "Ahoy, Captain, a narwhal off the larboard bow!\r\n" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | ".\\crowsnest.ps1 narwhal" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "Or \"an\" before a word starting with a vowel" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 2, 56 | "metadata": { 57 | "dotnet_interactive": { 58 | "language": "pwsh" 59 | }, 60 | "polyglot_notebook": { 61 | "kernelName": "pwsh" 62 | }, 63 | "vscode": { 64 | "languageId": "polyglot-notebook" 65 | } 66 | }, 67 | "outputs": [ 68 | { 69 | "name": "stdout", 70 | "output_type": "stream", 71 | "text": [ 72 | "Ahoy, Captain, an octopus off the larboard bow!\r\n" 73 | ] 74 | } 75 | ], 76 | "source": [ 77 | ".\\crowsnest.ps1 octopus" 78 | ] 79 | } 80 | ], 81 | "metadata": { 82 | "kernelspec": { 83 | "display_name": ".NET (PowerShell)", 84 | "language": "PowerShell", 85 | "name": ".net-powershell" 86 | }, 87 | "language_info": { 88 | "file_extension": ".ps1", 89 | "mimetype": "text/x-powershell", 90 | "name": "PowerShell", 91 | "pygments_lexer": "powershell", 92 | "version": "7.0" 93 | } 94 | }, 95 | "nbformat": 4, 96 | "nbformat_minor": 4 97 | } 98 | -------------------------------------------------------------------------------- /02_crowsnest/crowsnest.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [Parameter(Mandatory)] 18 | # A word 19 | $word 20 | ) 21 | 22 | $article = if ('aeiou'.IndexOf($word.ToLower()[0]) -ge 0) { 23 | "an" 24 | } 25 | else { 26 | "a" 27 | } 28 | 29 | "Ahoy, Captain, $($article) $($word) off the larboard bow!" 30 | -------------------------------------------------------------------------------- /02_crowsnest/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [Parameter(Mandatory)] 18 | # A word 19 | $word 20 | ) 21 | 22 | $article = if ('aeiou'.IndexOf($word.ToLower()[0]) -ge 0) { 23 | "an" 24 | } 25 | else { 26 | "a" 27 | } 28 | 29 | "Ahoy, Captain, $($article) $($word) off the larboard bow!" 30 | -------------------------------------------------------------------------------- /02_crowsnest/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/02_crowsnest/test.ps1 -------------------------------------------------------------------------------- /03_picnic/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/03_picnic/AllTest.ps1 -------------------------------------------------------------------------------- /03_picnic/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/03_picnic/README.md -------------------------------------------------------------------------------- /03_picnic/picnic.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Picnic\n", 8 | "\n", 9 | "Write a program that will correctly format the items we're taking on our picnic.\n", 10 | "For one item, it should print the one item.\n" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 2, 16 | "metadata": { 17 | "dotnet_interactive": { 18 | "language": "pwsh" 19 | }, 20 | "polyglot_notebook": { 21 | "kernelName": "pwsh" 22 | }, 23 | "vscode": { 24 | "languageId": "polyglot-notebook" 25 | } 26 | }, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "You are bringing sandwiches.\r\n" 33 | ] 34 | } 35 | ], 36 | "source": [ 37 | ".\\picnic.ps1 sandwiches" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "For two items, place \"and\" in between" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 3, 50 | "metadata": { 51 | "dotnet_interactive": { 52 | "language": "pwsh" 53 | }, 54 | "polyglot_notebook": { 55 | "kernelName": "pwsh" 56 | }, 57 | "vscode": { 58 | "languageId": "polyglot-notebook" 59 | } 60 | }, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "You are bringing sandwiches and chips.\r\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | ".\\picnic.ps1 sandwiches chips" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "For three or more items, use commas and \"and\"" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 4, 84 | "metadata": { 85 | "dotnet_interactive": { 86 | "language": "pwsh" 87 | }, 88 | "polyglot_notebook": { 89 | "kernelName": "pwsh" 90 | }, 91 | "vscode": { 92 | "languageId": "polyglot-notebook" 93 | } 94 | }, 95 | "outputs": [ 96 | { 97 | "name": "stdout", 98 | "output_type": "stream", 99 | "text": [ 100 | "You are bringing sandwiches, chips, and cake.\r\n" 101 | ] 102 | } 103 | ], 104 | "source": [ 105 | ".\\picnic.ps1 sandwiches chips cake" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "If the `-sorted` flag is present, the items should first be sorted" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 5, 118 | "metadata": { 119 | "dotnet_interactive": { 120 | "language": "pwsh" 121 | }, 122 | "polyglot_notebook": { 123 | "kernelName": "pwsh" 124 | }, 125 | "vscode": { 126 | "languageId": "polyglot-notebook" 127 | } 128 | }, 129 | "outputs": [ 130 | { 131 | "name": "stdout", 132 | "output_type": "stream", 133 | "text": [ 134 | "You are bringing cake, chips, and sandwiches.\r\n" 135 | ] 136 | } 137 | ], 138 | "source": [ 139 | ".\\picnic.ps1 sandwiches chips cake -sorted" 140 | ] 141 | } 142 | ], 143 | "metadata": { 144 | "kernelspec": { 145 | "display_name": ".NET (PowerShell)", 146 | "language": "PowerShell", 147 | "name": ".net-powershell" 148 | }, 149 | "language_info": { 150 | "file_extension": ".ps1", 151 | "mimetype": "text/x-powershell", 152 | "name": "PowerShell", 153 | "pygments_lexer": "powershell", 154 | "version": "7.0" 155 | } 156 | }, 157 | "nbformat": 4, 158 | "nbformat_minor": 4 159 | } 160 | -------------------------------------------------------------------------------- /03_picnic/picnic.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [Switch]$Sorted 18 | ) 19 | 20 | $list = $args 21 | if ($Sorted) { 22 | $list = $list | Sort-Object 23 | } 24 | 25 | $template = "You are bringing {0}." 26 | 27 | switch ($list.Count) { 28 | 1 { 29 | $template -f $list -join '' 30 | } 31 | 2 { 32 | $list[-1] = "and " + $list[-1] 33 | $template -f ($list -join ' ') 34 | } 35 | default { 36 | $list[-1] = "and " + $list[-1] 37 | $template -f ($list -join ', ') 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /03_picnic/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [Switch]$Sorted 18 | ) 19 | 20 | $list = $args 21 | if ($Sorted) { 22 | $list = $list | Sort-Object 23 | } 24 | 25 | $template = "You are bringing {0}." 26 | 27 | switch ($list.Count) { 28 | 1 { 29 | $template -f $list -join '' 30 | } 31 | 2 { 32 | $list[-1] = "and " + $list[-1] 33 | $template -f ($list -join ' ') 34 | } 35 | default { 36 | $list[-1] = "and " + $list[-1] 37 | $template -f ($list -join ', ') 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /03_picnic/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/03_picnic/test.ps1 -------------------------------------------------------------------------------- /04_jump_the_five/04_jump_the_five.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/04_jump_the_five/04_jump_the_five.ps1 -------------------------------------------------------------------------------- /04_jump_the_five/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/04_jump_the_five/AllTest.ps1 -------------------------------------------------------------------------------- /04_jump_the_five/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/04_jump_the_five/README.md -------------------------------------------------------------------------------- /04_jump_the_five/jump.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Jump the Five\n", 8 | "\n", 9 | "Write a program that will encode any number in a given string using an algorithm to \"jump the five\" on a standard US telephone keypad such that \"1\" becomes \"9,\" \"4\" becomes \"6,\" etc. \n", 10 | "The \"5\" and the \"0\" will swap with each other.\n", 11 | "\n", 12 | "```\n", 13 | "1 => 9\n", 14 | "2 => 8\n", 15 | "3 => 7\n", 16 | "4 => 6\n", 17 | "5 => 0\n", 18 | "6 => 4\n", 19 | "7 => 3\n", 20 | "8 => 2\n", 21 | "9 => 1\n", 22 | "0 => 5\n", 23 | "```" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "Encode only the numbers and leave all other text alone" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 1, 36 | "metadata": { 37 | "dotnet_interactive": { 38 | "language": "pwsh" 39 | }, 40 | "polyglot_notebook": { 41 | "kernelName": "pwsh" 42 | }, 43 | "vscode": { 44 | "languageId": "polyglot-notebook" 45 | } 46 | }, 47 | "outputs": [ 48 | { 49 | "name": "stdout", 50 | "output_type": "stream", 51 | "text": [ 52 | "243-0751\r\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "./jump.ps1 867-5309" 58 | ] 59 | } 60 | ], 61 | "metadata": { 62 | "kernelspec": { 63 | "display_name": ".NET (PowerShell)", 64 | "language": "PowerShell", 65 | "name": ".net-powershell" 66 | }, 67 | "language_info": { 68 | "file_extension": ".ps1", 69 | "mimetype": "text/x-powershell", 70 | "name": "PowerShell", 71 | "pygments_lexer": "powershell", 72 | "version": "7.0" 73 | } 74 | }, 75 | "nbformat": 4, 76 | "nbformat_minor": 4 77 | } 78 | -------------------------------------------------------------------------------- /04_jump_the_five/jump.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $number 18 | ) 19 | 20 | $map = @{ 21 | '1' = '9' 22 | '2' = '8' 23 | '3' = '7' 24 | '4' = '6' 25 | '5' = '0' 26 | '6' = '4' 27 | '7' = '3' 28 | '8' = '2' 29 | '9' = '1' 30 | '0' = '5' 31 | } 32 | 33 | -join ( 34 | $number.ToCharArray() | ForEach-Object { 35 | $key = $_.ToString() 36 | if ($map.ContainsKey($key)) { 37 | $map.$key 38 | } 39 | else { 40 | $key 41 | } 42 | } 43 | ) 44 | -------------------------------------------------------------------------------- /04_jump_the_five/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $number 18 | ) 19 | 20 | $map = @{ 21 | '1' = '9' 22 | '2' = '8' 23 | '3' = '7' 24 | '4' = '6' 25 | '5' = '0' 26 | '6' = '4' 27 | '7' = '3' 28 | '8' = '2' 29 | '9' = '1' 30 | '0' = '5' 31 | } 32 | 33 | -join ( 34 | $number.ToCharArray() | ForEach-Object { 35 | $key = $_.ToString() 36 | if ($map.ContainsKey($key)) { 37 | $map.$key 38 | } 39 | else { 40 | $key 41 | } 42 | } 43 | ) 44 | -------------------------------------------------------------------------------- /04_jump_the_five/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/04_jump_the_five/test.ps1 -------------------------------------------------------------------------------- /05_howler/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/05_howler/AllTest.ps1 -------------------------------------------------------------------------------- /05_howler/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/05_howler/README.md -------------------------------------------------------------------------------- /05_howler/howler.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Howler\n", 8 | "\n", 9 | "Write a program that uppercases the given text.\n" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.\r\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | "./howler.ps1 'The quick brown fox jumps over the lazy dog.'" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "If the text names a file, uppercase the contents of the file" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "metadata": { 50 | "dotnet_interactive": { 51 | "language": "pwsh" 52 | }, 53 | "polyglot_notebook": { 54 | "kernelName": "pwsh" 55 | }, 56 | "vscode": { 57 | "languageId": "polyglot-notebook" 58 | } 59 | }, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.\r\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "./howler.ps1 ../inputFiles/fox.txt" 71 | ] 72 | } 73 | ], 74 | "metadata": { 75 | "kernelspec": { 76 | "display_name": ".NET (PowerShell)", 77 | "language": "PowerShell", 78 | "name": ".net-powershell" 79 | }, 80 | "language_info": { 81 | "file_extension": ".ps1", 82 | "mimetype": "text/x-powershell", 83 | "name": "PowerShell", 84 | "pygments_lexer": "powershell", 85 | "version": "7.0" 86 | } 87 | }, 88 | "nbformat": 4, 89 | "nbformat_minor": 4 90 | } 91 | -------------------------------------------------------------------------------- /05_howler/howler.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $targetInput, 18 | $outFile 19 | ) 20 | 21 | if ( Test-Path $targetInput ) { 22 | $data = Get-Content -Raw $targetInput 23 | } 24 | elseif ($targetInput -is [string]) { 25 | $data = $targetInput 26 | } 27 | 28 | if ($outFile) { 29 | $data.ToUpper() | Set-Content $outFile -Encoding ascii 30 | } 31 | else { 32 | $data.ToUpper() 33 | } 34 | -------------------------------------------------------------------------------- /05_howler/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $targetInput, 18 | $outFile 19 | ) 20 | 21 | if ( Test-Path $targetInput ) { 22 | $data = Get-Content -Raw $targetInput 23 | } 24 | elseif ($targetInput -is [string]) { 25 | $data = $targetInput 26 | } 27 | 28 | if ($outFile) { 29 | $data.ToUpper() | Set-Content $outFile -Encoding ascii 30 | } 31 | else { 32 | $data.ToUpper() 33 | } 34 | -------------------------------------------------------------------------------- /05_howler/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/05_howler/test.ps1 -------------------------------------------------------------------------------- /06_wc/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/06_wc/AllTest.ps1 -------------------------------------------------------------------------------- /06_wc/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/06_wc/README.md -------------------------------------------------------------------------------- /06_wc/inputs/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/06_wc/inputs/empty.txt -------------------------------------------------------------------------------- /06_wc/inputs/foo.txt: -------------------------------------------------------------------------------- 1 | foo 2 | bar baz 3 | quux 4 | -------------------------------------------------------------------------------- /06_wc/inputs/one.txt: -------------------------------------------------------------------------------- 1 | a 2 | -------------------------------------------------------------------------------- /06_wc/inputs/two.txt: -------------------------------------------------------------------------------- 1 | a 2 | b 3 | -------------------------------------------------------------------------------- /06_wc/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [Parameter(ValueFromPipeline)] 18 | $file 19 | ) 20 | 21 | Begin { 22 | $list = @() 23 | } 24 | 25 | Process { 26 | if (Test-Path $file) { 27 | $contents = Get-Content -Raw $file 28 | } 29 | else { 30 | $contents = $file 31 | } 32 | } 33 | 34 | End { 35 | $lines = 0 36 | $words = 0 37 | $characters = 0 38 | 39 | if ($null -ne $contents) { 40 | $contents = $contents.Trim() 41 | 42 | $lines = $contents.Split("`n").Count 43 | $words = [regex]::Split($contents, '\W+').Count 44 | $characters = $contents.ToCharArray().Count 45 | } 46 | 47 | [PSCustomObject]@{ 48 | lines = $lines 49 | words = $words 50 | characters = $characters 51 | name = $file 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /06_wc/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/06_wc/test.ps1 -------------------------------------------------------------------------------- /06_wc/wc.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Word Count\n", 8 | "\n", 9 | "Write a PowerShell implementation of `wc` (word count).\n", 10 | "The program should print lines, words, and characters for each input.\n", 11 | "\n", 12 | "Files are acceptable arguments\n" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 1, 18 | "metadata": { 19 | "dotnet_interactive": { 20 | "language": "pwsh" 21 | }, 22 | "polyglot_notebook": { 23 | "kernelName": "pwsh" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "\n", 32 | "\u001b[32;1mlines words characters name\u001b[0m\n", 33 | "\u001b[32;1m----- ----- ---------- ----\u001b[0m\n", 34 | " 1 10 44 ..\\inputFiles\\fox.txt\n", 35 | "\n" 36 | ] 37 | } 38 | ], 39 | "source": [ 40 | ".\\wc.ps1 ..\\inputFiles\\fox.txt" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "As is \"standard in\" (`STDIN`) if given no arguments" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 2, 53 | "metadata": { 54 | "dotnet_interactive": { 55 | "language": "pwsh" 56 | }, 57 | "polyglot_notebook": { 58 | "kernelName": "pwsh" 59 | } 60 | }, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "\n", 67 | "\u001b[32;1mlines words characters name\u001b[0m\n", 68 | "\u001b[32;1m----- ----- ---------- ----\u001b[0m\n", 69 | " 1 10 44 The quick brown fox jumps over the lazy dog.\n", 70 | "\n" 71 | ] 72 | } 73 | ], 74 | "source": [ 75 | "cat ..\\inputFiles\\fox.txt | .\\wc.ps1" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "If given more than one file, also include a summary for each column" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 3, 88 | "metadata": { 89 | "dotnet_interactive": { 90 | "language": "pwsh" 91 | }, 92 | "polyglot_notebook": { 93 | "kernelName": "pwsh" 94 | } 95 | }, 96 | "outputs": [ 97 | { 98 | "name": "stdout", 99 | "output_type": "stream", 100 | "text": [ 101 | "\n", 102 | "\u001b[32;1m lines words characters name\u001b[0m\n", 103 | "\u001b[32;1m ----- ----- ---------- ----\u001b[0m\n", 104 | "249166 340980 3333150 ..\\inputFiles\\*.txt\n", 105 | "\n" 106 | ] 107 | } 108 | ], 109 | "source": [ 110 | ".\\wc.ps1 ..\\inputFiles\\*.txt" 111 | ] 112 | } 113 | ], 114 | "metadata": { 115 | "kernelspec": { 116 | "display_name": ".NET (C#)", 117 | "language": "C#", 118 | "name": ".net-csharp" 119 | }, 120 | "language_info": { 121 | "file_extension": ".ps1", 122 | "mimetype": "text/x-powershell", 123 | "name": "polyglot-notebook", 124 | "pygments_lexer": "powershell", 125 | "version": "7.0" 126 | }, 127 | "polyglot_notebook": { 128 | "kernelInfo": { 129 | "defaultKernelName": "csharp", 130 | "items": [ 131 | { 132 | "aliases": [], 133 | "name": "csharp" 134 | }, 135 | { 136 | "aliases": [], 137 | "name": "powershell" 138 | } 139 | ] 140 | } 141 | } 142 | }, 143 | "nbformat": 4, 144 | "nbformat_minor": 4 145 | } 146 | -------------------------------------------------------------------------------- /06_wc/wc.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [Parameter(ValueFromPipeline)] 18 | $file 19 | ) 20 | 21 | Begin { 22 | $list = @() 23 | } 24 | 25 | Process { 26 | if (Test-Path $file) { 27 | $contents = Get-Content -Raw $file 28 | } 29 | else { 30 | $contents = $file 31 | } 32 | } 33 | 34 | End { 35 | $lines = 0 36 | $words = 0 37 | $characters = 0 38 | 39 | if ($null -ne $contents) { 40 | $contents = $contents.Trim() 41 | 42 | $lines = $contents.Split("`n").Count 43 | $words = [regex]::Split($contents, '\W+').Count 44 | $characters = $contents.ToCharArray().Count 45 | } 46 | 47 | [PSCustomObject]@{ 48 | lines = $lines 49 | words = $words 50 | characters = $characters 51 | name = $file 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /07_gashlycrumb/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/07_gashlycrumb/AllTest.ps1 -------------------------------------------------------------------------------- /07_gashlycrumb/Gashlycrumb.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Gashlycrumb\n", 8 | "\n", 9 | "Write a program that prints the line from a file starting with a given letter\n" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "A is for Amy who fell down the stairs.\r\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | ".\\gashlycrumb.ps1 a" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "By default, the `-f` or `--file` should use the included `gashlycrumb.txt` file, but can be overridden" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "metadata": { 50 | "dotnet_interactive": { 51 | "language": "pwsh" 52 | }, 53 | "polyglot_notebook": { 54 | "kernelName": "pwsh" 55 | }, 56 | "vscode": { 57 | "languageId": "polyglot-notebook" 58 | } 59 | }, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "A is for Alfred, poisoned to death.\r\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | ".\\gashlycrumb.ps1 a -f alternate.txt" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "The program should accept one or more letters as positional arguments, printing each line or a message that the given argument is not present in the file\n" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "The program should accept one or more letters as positional arguments, printing each line or a message that the given argument is not present in the file" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 3, 90 | "metadata": { 91 | "dotnet_interactive": { 92 | "language": "pwsh" 93 | }, 94 | "polyglot_notebook": { 95 | "kernelName": "pwsh" 96 | }, 97 | "vscode": { 98 | "languageId": "polyglot-notebook" 99 | } 100 | }, 101 | "outputs": [ 102 | { 103 | "name": "stdout", 104 | "output_type": "stream", 105 | "text": [ 106 | "X is for Xavier, stuck through with a prong.\r\n" 107 | ] 108 | } 109 | ], 110 | "source": [ 111 | ".\\gashlycrumb.ps1 x 4 z -f alternate.txt" 112 | ] 113 | } 114 | ], 115 | "metadata": { 116 | "kernelspec": { 117 | "display_name": ".NET (PowerShell)", 118 | "language": "PowerShell", 119 | "name": ".net-powershell" 120 | }, 121 | "language_info": { 122 | "file_extension": ".ps1", 123 | "mimetype": "text/x-powershell", 124 | "name": "PowerShell", 125 | "pygments_lexer": "powershell", 126 | "version": "7.0" 127 | } 128 | }, 129 | "nbformat": 4, 130 | "nbformat_minor": 4 131 | } 132 | -------------------------------------------------------------------------------- /07_gashlycrumb/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/07_gashlycrumb/README.md -------------------------------------------------------------------------------- /07_gashlycrumb/alternate.txt: -------------------------------------------------------------------------------- 1 | A is for Alfred, poisoned to death. 2 | B is for Bertrand, consumed by meth. 3 | C is for Cornell, who ate some glass. 4 | D is for Donald, who died from gas. 5 | E is for Edward, hanged by the neck. 6 | F is for Freddy, crushed in a wreck. 7 | G is for Geoffrey, who slit his wrist. 8 | H is for Henry, who's neck got a twist. 9 | I is for Ingrid, who tripped down a stair. 10 | J is for Jered, who fell off a chair. 11 | K is for Kevin, bit by a snake. 12 | L is for Lauryl, impaled on a stake. 13 | M is for Moira, hit by a brick. 14 | N is for Norbert, who swallowed a stick. 15 | O is for Orville, who fell in a canyon. 16 | P is for Paul, strangled by his banyan. 17 | Q is for Quintanna, flayed in the night. 18 | R is for Robert, who died of spite. 19 | S is for Susan, stung by a jelly. 20 | T is for Terrange, kicked in the belly. 21 | U is for Uma, who's life was vanquished. 22 | V is for Victor, consumed by anguish. 23 | W is for Walter, who's socks were too long. 24 | X is for Xavier, stuck through with a prong. 25 | Y is for Yoeman, too fat by a piece. 26 | Z is for Zora, smothered by a fleece. 27 | -------------------------------------------------------------------------------- /07_gashlycrumb/gashlycrumb.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $vars, 18 | $file = "$PSScriptRoot\gashlycrumb.txt" 19 | ) 20 | 21 | foreach ($item in $vars) { 22 | $r = Get-Content $file | Where-Object { $_ -match "^$item " } 23 | if($r) { 24 | $r 25 | } else { 26 | 'I do not know "{0}".' -f $item 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /07_gashlycrumb/gashlycrumb.txt: -------------------------------------------------------------------------------- 1 | A is for Amy who fell down the stairs. 2 | B is for Basil assaulted by bears. 3 | C is for Clara who wasted away. 4 | D is for Desmond thrown out of a sleigh. 5 | E is for Ernest who choked on a peach. 6 | F is for Fanny sucked dry by a leech. 7 | G is for George smothered under a rug. 8 | H is for Hector done in by a thug. 9 | I is for Ida who drowned in a lake. 10 | J is for James who took lye by mistake. 11 | K is for Kate who was struck with an axe. 12 | L is for Leo who choked on some tacks. 13 | M is for Maud who was swept out to sea. 14 | N is for Neville who died of ennui. 15 | O is for Olive run through with an awl. 16 | P is for Prue trampled flat in a brawl. 17 | Q is for Quentin who sank on a mire. 18 | R is for Rhoda consumed by a fire. 19 | S is for Susan who perished of fits. 20 | T is for Titus who flew into bits. 21 | U is for Una who slipped down a drain. 22 | V is for Victor squashed under a train. 23 | W is for Winnie embedded in ice. 24 | X is for Xerxes devoured by mice. 25 | Y is for Yorick whose head was bashed in. 26 | Z is for Zillah who drank too much gin. 27 | -------------------------------------------------------------------------------- /07_gashlycrumb/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $vars, 18 | $file = "$PSScriptRoot\gashlycrumb.txt" 19 | ) 20 | 21 | foreach ($item in $vars) { 22 | $r = Get-Content $file | Where-Object { $_ -match "^$item " } 23 | if($r) { 24 | $r 25 | } else { 26 | 'I do not know "{0}".' -f $item 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /07_gashlycrumb/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/07_gashlycrumb/test.ps1 -------------------------------------------------------------------------------- /08_apples_and_bananas/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/08_apples_and_bananas/AllTest.ps1 -------------------------------------------------------------------------------- /08_apples_and_bananas/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/08_apples_and_bananas/README.md -------------------------------------------------------------------------------- /08_apples_and_bananas/apples.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Apples and Bananas\n", 8 | "\n", 9 | "Write a program that will substitute all the vowels in a given text with a single vowel (default \"a\")\n" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "Tha qaack brawn fax jamps avar tha lazy dag.\r\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | ".\\apples.ps1 'The quick brown fox jumps over the lazy dog.'" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "The argument may name a file in which case you should read the contents of that file. In addition the -vowel command line argument can be passed to override the default character (a)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "metadata": { 50 | "dotnet_interactive": { 51 | "language": "pwsh" 52 | }, 53 | "polyglot_notebook": { 54 | "kernelName": "pwsh" 55 | }, 56 | "vscode": { 57 | "languageId": "polyglot-notebook" 58 | } 59 | }, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "Thu quuck bruwn fux jumps uvur thu luzy dug.\r\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | ".\\apples.ps1 ..\\inputFiles\\fox.txt -vowel u" 71 | ] 72 | } 73 | ], 74 | "metadata": { 75 | "kernelspec": { 76 | "display_name": ".NET (PowerShell)", 77 | "language": "PowerShell", 78 | "name": ".net-powershell" 79 | }, 80 | "language_info": { 81 | "file_extension": ".ps1", 82 | "mimetype": "text/x-powershell", 83 | "name": "PowerShell", 84 | "pygments_lexer": "powershell", 85 | "version": "7.0" 86 | } 87 | }, 88 | "nbformat": 4, 89 | "nbformat_minor": 4 90 | } 91 | -------------------------------------------------------------------------------- /08_apples_and_bananas/apples.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $s, 18 | [ValidateSet('a', 'e', 'i', 'o', 'u')] 19 | $vowel = 'a' 20 | ) 21 | 22 | if (Test-Path $s) { 23 | $s = Get-Content -Raw $s 24 | } 25 | 26 | $evaluator = { 27 | param($targetMatch) 28 | 29 | if ([char]::IsUpper($targetMatch.value)) { 30 | $vowel.ToUpper() 31 | } 32 | else { 33 | $vowel.ToLower() 34 | } 35 | } 36 | 37 | [regex]::Replace($s, "(?i)[aeiou]", $evaluator) 38 | -------------------------------------------------------------------------------- /08_apples_and_bananas/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $s, 18 | [ValidateSet('a', 'e', 'i', 'o', 'u')] 19 | $vowel = 'a' 20 | ) 21 | 22 | if (Test-Path $s) { 23 | $s = Get-Content -Raw $s 24 | } 25 | 26 | $evaluator = { 27 | param($targetMatch) 28 | 29 | if ([char]::IsUpper($targetMatch.value)) { 30 | $vowel.ToUpper() 31 | } 32 | else { 33 | $vowel.ToLower() 34 | } 35 | } 36 | 37 | [regex]::Replace($s, "(?i)[aeiou]", $evaluator) 38 | -------------------------------------------------------------------------------- /08_apples_and_bananas/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/08_apples_and_bananas/test.ps1 -------------------------------------------------------------------------------- /09_abuse/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/09_abuse/AllTest.ps1 -------------------------------------------------------------------------------- /09_abuse/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/09_abuse/README.md -------------------------------------------------------------------------------- /09_abuse/abuse.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Shakespearean Insulter\n", 8 | "\n", 9 | "Write a Shakespearean insult generator\n" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "You loathsome, toad-spotted fiend!\n", 32 | "You sodden-witted, lecherous coward!\n", 33 | "You old, scurvy ratcatcher!\n" 34 | ] 35 | } 36 | ], 37 | "source": [ 38 | ".\\abuse.ps1" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "The program can vary the `-n` or `--number` of insults" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 2, 51 | "metadata": { 52 | "dotnet_interactive": { 53 | "language": "pwsh" 54 | }, 55 | "polyglot_notebook": { 56 | "kernelName": "pwsh" 57 | }, 58 | "vscode": { 59 | "languageId": "polyglot-notebook" 60 | } 61 | }, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "You peevish, scurilous boy!\n", 68 | "You irksome, caterwauling varlet!\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | ".\\abuse.ps1 -n 2" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "Or the number of `--adjectives` (also `-a`)" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 3, 86 | "metadata": { 87 | "dotnet_interactive": { 88 | "language": "pwsh" 89 | }, 90 | "polyglot_notebook": { 91 | "kernelName": "pwsh" 92 | }, 93 | "vscode": { 94 | "languageId": "polyglot-notebook" 95 | } 96 | }, 97 | "outputs": [ 98 | { 99 | "name": "stdout", 100 | "output_type": "stream", 101 | "text": [ 102 | "You toad-spotted, false, bankrupt, foolish lunatic!\n", 103 | "You thin-faced, cullionly, dishonest, infected Judas!\n", 104 | "You cullionly, foul, lubbery, scurvy butt!\n" 105 | ] 106 | } 107 | ], 108 | "source": [ 109 | ".\\abuse.ps1 -a 4" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "The program should accept a `-s` or `--seed` to set the random seed for reproducible results" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 4, 122 | "metadata": { 123 | "dotnet_interactive": { 124 | "language": "pwsh" 125 | }, 126 | "polyglot_notebook": { 127 | "kernelName": "pwsh" 128 | }, 129 | "vscode": { 130 | "languageId": "polyglot-notebook" 131 | } 132 | }, 133 | "outputs": [ 134 | { 135 | "name": "stdout", 136 | "output_type": "stream", 137 | "text": [ 138 | "You lecherous, scurilous maw!\n", 139 | "You thin-faced, caterwauling knave!\n", 140 | "You rotten, detestable braggart!\n" 141 | ] 142 | } 143 | ], 144 | "source": [ 145 | ".\\abuse.ps1 -s 1" 146 | ] 147 | } 148 | ], 149 | "metadata": { 150 | "kernelspec": { 151 | "display_name": ".NET (PowerShell)", 152 | "language": "PowerShell", 153 | "name": ".net-powershell" 154 | }, 155 | "language_info": { 156 | "file_extension": ".ps1", 157 | "mimetype": "text/x-powershell", 158 | "name": "PowerShell", 159 | "pygments_lexer": "powershell", 160 | "version": "7.0" 161 | } 162 | }, 163 | "nbformat": 4, 164 | "nbformat_minor": 4 165 | } 166 | -------------------------------------------------------------------------------- /09_abuse/abuse.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [int]$number = 3, 18 | [int]$adjectives = 2, 19 | [int]$seed 20 | ) 21 | 22 | Import-Module ..\UtilityModules\UtilityModules.psm1 23 | 24 | $adjectiveList = $( 25 | 'bankrupt' 26 | 'base' 27 | 'caterwauling' 28 | 'corrupt' 29 | 'cullionly' 30 | 'detestable' 31 | 'dishonest' 32 | 'false' 33 | 'filthsome' 34 | 'filthy' 35 | 'foolish' 36 | 'foul' 37 | 'gross' 38 | 'heedless' 39 | 'indistinguishable' 40 | 'infected' 41 | 'insatiate' 42 | 'irksome' 43 | 'lascivious' 44 | 'lecherous' 45 | 'loathsome' 46 | 'lubbery' 47 | 'old' 48 | 'peevish' 49 | 'rascaly' 50 | 'rotten' 51 | 'ruinous' 52 | 'scurilous' 53 | 'scurvy' 54 | 'slanderous' 55 | 'sodden-witted' 56 | 'thin-faced' 57 | 'toad-spotted' 58 | 'unmannered' 59 | 'vile wall-eyed' 60 | ) 61 | 62 | $nouns = $( 63 | 'Judas' 64 | 'Satan' 65 | 'ape' 66 | 'ass' 67 | 'barbermonger' 68 | 'beggar' 69 | 'block' 70 | 'boy' 71 | 'braggart' 72 | 'butt' 73 | 'carbuncle' 74 | 'coward' 75 | 'coxcomb' 76 | 'cur' 77 | 'dandy' 78 | 'degenerate' 79 | 'fiend' 80 | 'fishmonger' 81 | 'fool' 82 | 'gull' 83 | 'harpy' 84 | 'jack' 85 | 'jolthead' 86 | 'knave' 87 | 'liar' 88 | 'lunatic' 89 | 'maw' 90 | 'milksop' 91 | 'minion' 92 | 'ratcatcher' 93 | 'recreant' 94 | 'rogue' 95 | 'scold' 96 | 'slave' 97 | 'swine' 98 | 'traitor' 99 | 'varlet' 100 | 'villain' 101 | 'worm' 102 | ) 103 | 104 | if ($seed) { $null = Get-Random -SetSeed $seed } 105 | 106 | 1..$number | ForEach-Object { 107 | $choices = Get-RandomSample $adjectiveList $adjectives 108 | "You {0} {1}!" -f ($choices -join ', '), ($nouns | Get-Random ) 109 | } 110 | -------------------------------------------------------------------------------- /09_abuse/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [int]$number = 3, 18 | [int]$adjectives = 2, 19 | [int]$seed 20 | ) 21 | 22 | Import-Module ..\UtilityModules\UtilityModules.psm1 23 | 24 | $adjectiveList = $( 25 | 'bankrupt' 26 | 'base' 27 | 'caterwauling' 28 | 'corrupt' 29 | 'cullionly' 30 | 'detestable' 31 | 'dishonest' 32 | 'false' 33 | 'filthsome' 34 | 'filthy' 35 | 'foolish' 36 | 'foul' 37 | 'gross' 38 | 'heedless' 39 | 'indistinguishable' 40 | 'infected' 41 | 'insatiate' 42 | 'irksome' 43 | 'lascivious' 44 | 'lecherous' 45 | 'loathsome' 46 | 'lubbery' 47 | 'old' 48 | 'peevish' 49 | 'rascaly' 50 | 'rotten' 51 | 'ruinous' 52 | 'scurilous' 53 | 'scurvy' 54 | 'slanderous' 55 | 'sodden-witted' 56 | 'thin-faced' 57 | 'toad-spotted' 58 | 'unmannered' 59 | 'vile wall-eyed' 60 | ) 61 | 62 | $nouns = $( 63 | 'Judas' 64 | 'Satan' 65 | 'ape' 66 | 'ass' 67 | 'barbermonger' 68 | 'beggar' 69 | 'block' 70 | 'boy' 71 | 'braggart' 72 | 'butt' 73 | 'carbuncle' 74 | 'coward' 75 | 'coxcomb' 76 | 'cur' 77 | 'dandy' 78 | 'degenerate' 79 | 'fiend' 80 | 'fishmonger' 81 | 'fool' 82 | 'gull' 83 | 'harpy' 84 | 'jack' 85 | 'jolthead' 86 | 'knave' 87 | 'liar' 88 | 'lunatic' 89 | 'maw' 90 | 'milksop' 91 | 'minion' 92 | 'ratcatcher' 93 | 'recreant' 94 | 'rogue' 95 | 'scold' 96 | 'slave' 97 | 'swine' 98 | 'traitor' 99 | 'varlet' 100 | 'villain' 101 | 'worm' 102 | ) 103 | 104 | if ($seed) { $null = Get-Random -SetSeed $seed } 105 | 106 | 1..$number | ForEach-Object { 107 | $choices = Get-RandomSample $adjectiveList $adjectives 108 | "You {0} {1}!" -f ($choices -join ', '), ($nouns | Get-Random ) 109 | } 110 | -------------------------------------------------------------------------------- /09_abuse/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/09_abuse/test.ps1 -------------------------------------------------------------------------------- /10_telephone/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/10_telephone/AllTest.ps1 -------------------------------------------------------------------------------- /10_telephone/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/10_telephone/README.md -------------------------------------------------------------------------------- /10_telephone/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $text, 18 | $mutations = .1, 19 | $seed 20 | ) 21 | 22 | Import-Module ..\UtilityModules\UtilityModules.psm1 -Force 23 | 24 | if (Test-Path $text) { 25 | $text = Get-Content -Raw $text 26 | } 27 | 28 | if ($seed) { $null = Get-Random -SetSeed $seed } 29 | 30 | $alpha = (Get-AsciiLetters) + (Get-AsciiPunctuation) 31 | $lengthText = $text.Length 32 | $numMutations = [math]::Round($mutations * $lengthText) 33 | $newText = $text 34 | 35 | $positionList = Get-RandomSample (0..($lengthText - 1)) $numMutations 36 | foreach ($position in $positionList) { 37 | $newChar = $alpha.Replace($newText[$position], $null).ToCharArray() | Get-Random 38 | 39 | $first = $newText.Substring(0, $position) 40 | $rest = $newText.Substring($position + 1) 41 | $newText = "{0}{1}{2}" -f $first, $newChar, $rest 42 | } 43 | 44 | @" 45 | You said: "{0}" 46 | I heard : "{1}" 47 | "@ -f $text, $newText 48 | -------------------------------------------------------------------------------- /10_telephone/telephone.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Telephone\n", 8 | "\n", 9 | "Write a program that randomly mutates some given text which may be given on the command line\n" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "You said: \"The quick brown fox jumps over the lazy dog.\"\r\n", 32 | "I heard : \"The quick brkwn foU jumrs over thJ lazy dog.\"\r\n" 33 | ] 34 | } 35 | ], 36 | "source": [ 37 | ".\\telephone.ps1 'The quick brown fox jumps over the lazy dog.'" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "Or from a file" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 2, 50 | "metadata": { 51 | "dotnet_interactive": { 52 | "language": "pwsh" 53 | }, 54 | "polyglot_notebook": { 55 | "kernelName": "pwsh" 56 | }, 57 | "vscode": { 58 | "languageId": "polyglot-notebook" 59 | } 60 | }, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "You said: \"The quick brown fox jumps over the lazy dog.\"\r\n", 67 | "I heard : \"/he quiWk brown fBxujumps over the lazy dog.\"\r\n" 68 | ] 69 | } 70 | ], 71 | "source": [ 72 | " .\\telephone.ps1 ../inputFiles/fox.txt" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": {}, 78 | "source": [ 79 | "The program should accept a `-m` or `--mutations` that is a floating point number between 0 and 1 that represents a percentage of mutations to introduce\n" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 3, 85 | "metadata": { 86 | "dotnet_interactive": { 87 | "language": "pwsh" 88 | }, 89 | "polyglot_notebook": { 90 | "kernelName": "pwsh" 91 | }, 92 | "vscode": { 93 | "languageId": "polyglot-notebook" 94 | } 95 | }, 96 | "outputs": [ 97 | { 98 | "name": "stdout", 99 | "output_type": "stream", 100 | "text": [ 101 | "You said: \"The quick brown fox jumps over the lazy dog.\"\r\n", 102 | "I heard : \"LhmaNui\\kW>r]wn qMx YCxws o`FvQtheyl*zP dogh\"\r\n" 103 | ] 104 | } 105 | ], 106 | "source": [ 107 | ".\\telephone.ps1 -m .5 ../inputFiles/fox.txt" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "It should also accept a `-s` or `-seed` argument for the random seed to ensure reproducible results" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 4, 120 | "metadata": { 121 | "dotnet_interactive": { 122 | "language": "pwsh" 123 | }, 124 | "polyglot_notebook": { 125 | "kernelName": "pwsh" 126 | }, 127 | "vscode": { 128 | "languageId": "polyglot-notebook" 129 | } 130 | }, 131 | "outputs": [ 132 | { 133 | "name": "stdout", 134 | "output_type": "stream", 135 | "text": [ 136 | "You said: \"The quick brown fox jumps over the lazy dog.\"\r\n", 137 | "I heard : \"The quick\\brown fox jNyps over tGe lazy dog.\"\r\n" 138 | ] 139 | } 140 | ], 141 | "source": [ 142 | ".\\telephone.ps1 -s 2 ../inputFiles/fox.txt" 143 | ] 144 | } 145 | ], 146 | "metadata": { 147 | "kernelspec": { 148 | "display_name": ".NET (PowerShell)", 149 | "language": "PowerShell", 150 | "name": ".net-powershell" 151 | }, 152 | "language_info": { 153 | "file_extension": ".ps1", 154 | "mimetype": "text/x-powershell", 155 | "name": "PowerShell", 156 | "pygments_lexer": "powershell", 157 | "version": "7.0" 158 | } 159 | }, 160 | "nbformat": 4, 161 | "nbformat_minor": 4 162 | } 163 | -------------------------------------------------------------------------------- /10_telephone/telephone.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $text, 18 | $mutations = .1, 19 | $seed 20 | ) 21 | 22 | Import-Module ..\UtilityModules\UtilityModules.psm1 -Force 23 | 24 | if (Test-Path $text) { 25 | $text = Get-Content -Raw $text 26 | } 27 | 28 | if ($seed) { $null = Get-Random -SetSeed $seed } 29 | 30 | $alpha = (Get-AsciiLetters) + (Get-AsciiPunctuation) 31 | $lengthText = $text.Length 32 | $numMutations = [math]::Round($mutations * $lengthText) 33 | $newText = $text 34 | 35 | $positionList = Get-RandomSample (0..($lengthText - 1)) $numMutations 36 | foreach ($position in $positionList) { 37 | $newChar = $alpha.Replace($newText[$position], $null).ToCharArray() | Get-Random 38 | 39 | $first = $newText.Substring(0, $position) 40 | $rest = $newText.Substring($position + 1) 41 | $newText = "{0}{1}{2}" -f $first, $newChar, $rest 42 | } 43 | 44 | @" 45 | You said: "{0}" 46 | I heard : "{1}" 47 | "@ -f $text, $newText 48 | -------------------------------------------------------------------------------- /10_telephone/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/10_telephone/test.ps1 -------------------------------------------------------------------------------- /11_bottles_of_beer/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/11_bottles_of_beer/AllTest.ps1 -------------------------------------------------------------------------------- /11_bottles_of_beer/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/11_bottles_of_beer/README.md -------------------------------------------------------------------------------- /11_bottles_of_beer/bottles.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 99 Bottles of Beer\n", 8 | "\n", 9 | "Write a song that will generate the verses to the song \"99 Bottles of Beer\"\n" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "10 bottles of beer on the wall,\r\n", 32 | "10 bottles of beer,\r\n", 33 | "Take one down, pass it around,\r\n", 34 | "9 bottles of beer on the wall!\r\n", 35 | "9 bottles of beer on the wall,\r\n", 36 | "9 bottles of beer,\r\n", 37 | "Take one down, pass it around,\r\n", 38 | "8 bottles of beer on the wall!\r\n", 39 | "8 bottles of beer on the wall,\r\n", 40 | "8 bottles of beer,\r\n", 41 | "Take one down, pass it around,\r\n", 42 | "7 bottles of beer on the wall!\r\n", 43 | "7 bottles of beer on the wall,\r\n", 44 | "7 bottles of beer,\r\n", 45 | "Take one down, pass it around,\r\n", 46 | "6 bottles of beer on the wall!\r\n", 47 | "6 bottles of beer on the wall,\r\n", 48 | "6 bottles of beer,\r\n", 49 | "Take one down, pass it around,\r\n", 50 | "5 bottles of beer on the wall!\r\n", 51 | "5 bottles of beer on the wall,\r\n", 52 | "5 bottles of beer,\r\n", 53 | "Take one down, pass it around,\r\n", 54 | "4 bottles of beer on the wall!\r\n", 55 | "4 bottles of beer on the wall,\r\n", 56 | "4 bottles of beer,\r\n", 57 | "Take one down, pass it around,\r\n", 58 | "3 bottles of beer on the wall!\r\n", 59 | "3 bottles of beer on the wall,\r\n", 60 | "3 bottles of beer,\r\n", 61 | "Take one down, pass it around,\r\n", 62 | "2 bottles of beer on the wall!\r\n", 63 | "2 bottles of beer on the wall,\r\n", 64 | "2 bottles of beer,\r\n", 65 | "Take one down, pass it around,\r\n", 66 | "1 bottle of beer on the wall!\r\n", 67 | "1 bottle of beer on the wall,\r\n", 68 | "1 bottle of beer,\r\n", 69 | "Take one down, pass it around,\r\n", 70 | "No more bottles of beer on the wall!\r\n", 71 | "\r\n" 72 | ] 73 | } 74 | ], 75 | "source": [ 76 | "./bottles.ps1 | Select-Object -Last 2" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "If given a `-n` or `--num` argument, generate the verses from that number down to 0" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 2, 89 | "metadata": { 90 | "dotnet_interactive": { 91 | "language": "pwsh" 92 | }, 93 | "polyglot_notebook": { 94 | "kernelName": "pwsh" 95 | }, 96 | "vscode": { 97 | "languageId": "polyglot-notebook" 98 | } 99 | }, 100 | "outputs": [ 101 | { 102 | "name": "stdout", 103 | "output_type": "stream", 104 | "text": [ 105 | "2 bottles of beer on the wall,\r\n", 106 | "2 bottles of beer,\r\n", 107 | "Take one down, pass it around,\r\n", 108 | "1 bottle of beer on the wall!\r\n", 109 | "1 bottle of beer on the wall,\r\n", 110 | "1 bottle of beer,\r\n", 111 | "Take one down, pass it around,\r\n", 112 | "No more bottles of beer on the wall!\r\n", 113 | "\r\n" 114 | ] 115 | } 116 | ], 117 | "source": [ 118 | " ./bottles.ps1 -n 2" 119 | ] 120 | } 121 | ], 122 | "metadata": { 123 | "kernelspec": { 124 | "display_name": ".NET (PowerShell)", 125 | "language": "PowerShell", 126 | "name": ".net-powershell" 127 | }, 128 | "language_info": { 129 | "file_extension": ".ps1", 130 | "mimetype": "text/x-powershell", 131 | "name": "PowerShell", 132 | "pygments_lexer": "powershell", 133 | "version": "7.0" 134 | } 135 | }, 136 | "nbformat": 4, 137 | "nbformat_minor": 4 138 | } 139 | -------------------------------------------------------------------------------- /11_bottles_of_beer/bottles.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [ValidateRange(1, [int]::MaxValue)] 18 | $num = 10 19 | ) 20 | 21 | $result = for ($bottle = $num; $bottle -gt 0; $bottle--) { 22 | $nextBottle = $bottle - 1 23 | 24 | $s1 = '' 25 | $s2 = '' 26 | $numNext = 'No more' 27 | 28 | if ($bottle -gt 1) { $s1 = 's' } 29 | if ($nextBottle -ne 1) { $s2 = 's' } 30 | 31 | if ($nextBottle -gt 0) { $numNext = $nextBottle } 32 | 33 | @" 34 | $bottle bottle$($s1) of beer on the wall, 35 | $bottle bottle$($s1) of beer, 36 | Take one down, pass it around, 37 | $numNext bottle$($s2) of beer on the wall! 38 | 39 | "@ 40 | } 41 | 42 | -join $result 43 | -------------------------------------------------------------------------------- /11_bottles_of_beer/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [ValidateRange(1, [int]::MaxValue)] 18 | $num = 10 19 | ) 20 | 21 | $result = for ($bottle = $num; $bottle -gt 0; $bottle--) { 22 | $nextBottle = $bottle - 1 23 | 24 | $s1 = '' 25 | $s2 = '' 26 | $numNext = 'No more' 27 | 28 | if ($bottle -gt 1) { $s1 = 's' } 29 | if ($nextBottle -ne 1) { $s2 = 's' } 30 | 31 | if ($nextBottle -gt 0) { $numNext = $nextBottle } 32 | 33 | @" 34 | $bottle bottle$($s1) of beer on the wall, 35 | $bottle bottle$($s1) of beer, 36 | Take one down, pass it around, 37 | $numNext bottle$($s2) of beer on the wall! 38 | 39 | "@ 40 | } 41 | 42 | -join $result 43 | -------------------------------------------------------------------------------- /11_bottles_of_beer/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/11_bottles_of_beer/test.ps1 -------------------------------------------------------------------------------- /12_ransom/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/12_ransom/AllTest.ps1 -------------------------------------------------------------------------------- /12_ransom/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/12_ransom/README.md -------------------------------------------------------------------------------- /12_ransom/ransom.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Ransom\n", 8 | "\n", 9 | "Write a program that will randomly capitalize the letters in a given piece of text a la a ransom note.\n", 10 | "The text may be provided on the command line" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 1, 16 | "metadata": { 17 | "dotnet_interactive": { 18 | "language": "pwsh" 19 | }, 20 | "polyglot_notebook": { 21 | "kernelName": "pwsh" 22 | }, 23 | "vscode": { 24 | "languageId": "polyglot-notebook" 25 | } 26 | }, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "tHE QUIcK bRoWn fOX JUMps oveR THE lAzy DoG.\r\n" 33 | ] 34 | } 35 | ], 36 | "source": [ 37 | "./ransom.ps1 'The quick brown fox jumps over the lazy dog.'" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "Or with a file" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 2, 50 | "metadata": { 51 | "dotnet_interactive": { 52 | "language": "pwsh" 53 | }, 54 | "polyglot_notebook": { 55 | "kernelName": "pwsh" 56 | }, 57 | "vscode": { 58 | "languageId": "polyglot-notebook" 59 | } 60 | }, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "THe qUiCK BRowN FoX juMPS oVeR tHE LazY DOG.\r\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "./ransom.ps1 ../inputFiles/fox.txt" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "The program should accept a `-s` or `--seed` option to use as a random seed to ensure reproducibility" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 3, 84 | "metadata": { 85 | "dotnet_interactive": { 86 | "language": "pwsh" 87 | }, 88 | "polyglot_notebook": { 89 | "kernelName": "pwsh" 90 | }, 91 | "vscode": { 92 | "languageId": "polyglot-notebook" 93 | } 94 | }, 95 | "outputs": [ 96 | { 97 | "name": "stdout", 98 | "output_type": "stream", 99 | "text": [ 100 | "tHE qUick BrOwn fox jumps OvEr tHE LazY DOG.\r\n" 101 | ] 102 | } 103 | ], 104 | "source": [ 105 | "./ransom.ps1 -s 1 ../inputFiles/fox.txt" 106 | ] 107 | } 108 | ], 109 | "metadata": { 110 | "kernelspec": { 111 | "display_name": ".NET (PowerShell)", 112 | "language": "PowerShell", 113 | "name": ".net-powershell" 114 | }, 115 | "language_info": { 116 | "file_extension": ".ps1", 117 | "mimetype": "text/x-powershell", 118 | "name": "PowerShell", 119 | "pygments_lexer": "powershell", 120 | "version": "7.0" 121 | } 122 | }, 123 | "nbformat": 4, 124 | "nbformat_minor": 4 125 | } 126 | -------------------------------------------------------------------------------- /12_ransom/ransom.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [Parameter(Mandatory)] 18 | $text, 19 | $seed 20 | ) 21 | 22 | if ($seed) { $null = Get-Random -SetSeed $seed } 23 | 24 | if (Test-Path $text) { $text = Get-Content -Raw $text } 25 | function choose { 26 | param($char) 27 | 28 | if (Get-Random -Minimum 0 -Maximum 2) { 29 | [char]::ToUpper($char) 30 | } 31 | else { 32 | [char]::ToLower($char) 33 | } 34 | } 35 | 36 | $ransom = @() 37 | 38 | foreach ($char in $text.ToCharArray()) { 39 | $ransom += choose $char 40 | } 41 | 42 | -join $ransom 43 | -------------------------------------------------------------------------------- /12_ransom/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [Parameter(Mandatory)] 18 | $text, 19 | $seed 20 | ) 21 | 22 | if ($seed) { $null = Get-Random -SetSeed $seed } 23 | 24 | if (Test-Path $text) { $text = Get-Content -Raw $text } 25 | function choose { 26 | param($char) 27 | 28 | if (Get-Random -Minimum 0 -Maximum 2) { 29 | [char]::ToUpper($char) 30 | } 31 | else { 32 | [char]::ToLower($char) 33 | } 34 | } 35 | 36 | $ransom = @() 37 | 38 | foreach ($char in $text.ToCharArray()) { 39 | $ransom += choose $char 40 | } 41 | 42 | -join $ransom 43 | -------------------------------------------------------------------------------- /12_ransom/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/12_ransom/test.ps1 -------------------------------------------------------------------------------- /13_twelve_days/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/13_twelve_days/AllTest.ps1 -------------------------------------------------------------------------------- /13_twelve_days/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/13_twelve_days/README.md -------------------------------------------------------------------------------- /13_twelve_days/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [ValidateRange(1, 12)] 18 | [int]$num = 12, 19 | $outFile 20 | ) 21 | 22 | function verse { 23 | param($day) 24 | 25 | $ordinal = 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 26 | 'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth' 27 | 28 | $gifts = 'A partridge in a pear tree.', 29 | 'Two turtle doves,', 30 | 'Three French hens,', 31 | 'Four calling birds,', 32 | 'Five gold rings,', 33 | 'Six geese a laying,', 34 | 'Seven swans a swimming,', 35 | 'Eight maids a milking,', 36 | 'Nine ladies dancing,', 37 | 'Ten lords a leaping,', 38 | 'Eleven pipers piping,', 39 | 'Twelve drummers drumming,' 40 | 41 | $lines = @( 42 | "On the $($ordinal[$day]) day of Christmas,", 43 | 'My true love gave to me,' 44 | ) 45 | 46 | $reversedGifts = $gifts[0..$day] 47 | [array]::Reverse($reversedGifts) 48 | $lines += $reversedGifts 49 | 50 | if ($day -ge 1) { 51 | $lines[-1] = 'And ' + $lines[-1].ToLower() 52 | } 53 | 54 | $lines 55 | } 56 | 57 | $result = 0..($num - 1) | ForEach-Object { 58 | verse $_ 59 | } 60 | 61 | if ($outFile) { 62 | $result | Set-Content $outFile 63 | } 64 | else { 65 | $result -join "`r`n" 66 | } 67 | -------------------------------------------------------------------------------- /13_twelve_days/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/13_twelve_days/test.ps1 -------------------------------------------------------------------------------- /13_twelve_days/twelve_days.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Twelve Days of Christmas\n", 8 | "\n", 9 | "Write a program that will generate the verse \"The Twelve Days of Christmas\" song" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "Ten lords a leaping,\n", 32 | "Nine ladies dancing,\n", 33 | "Eight maids a milking,\n", 34 | "Seven swans a swimming,\n", 35 | "Six geese a laying,\n", 36 | "Five gold rings,\n", 37 | "Four calling birds,\n", 38 | "Three French hens,\n", 39 | "Two turtle doves,\n", 40 | "And a partridge in a pear tree.\n" 41 | ] 42 | } 43 | ], 44 | "source": [ 45 | "(./twelve_days.ps1).split(\"`n\") | select -last 10" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "The program should accept a `-n` or `--number` (default 12) to control the number of verses that are generated" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 2, 58 | "metadata": { 59 | "dotnet_interactive": { 60 | "language": "pwsh" 61 | }, 62 | "polyglot_notebook": { 63 | "kernelName": "pwsh" 64 | }, 65 | "vscode": { 66 | "languageId": "polyglot-notebook" 67 | } 68 | }, 69 | "outputs": [ 70 | { 71 | "name": "stdout", 72 | "output_type": "stream", 73 | "text": [ 74 | "On the first day of Christmas,\r\n", 75 | "My true love gave to me,\r\n", 76 | "A partridge in a pear tree.\r\n", 77 | "On the second day of Christmas,\r\n", 78 | "My true love gave to me,\r\n", 79 | "Two turtle doves,\r\n", 80 | "And a partridge in a pear tree.\r\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "./twelve_days.ps1 -n 2" 86 | ] 87 | } 88 | ], 89 | "metadata": { 90 | "kernelspec": { 91 | "display_name": ".NET (PowerShell)", 92 | "language": "PowerShell", 93 | "name": ".net-powershell" 94 | }, 95 | "language_info": { 96 | "file_extension": ".ps1", 97 | "mimetype": "text/x-powershell", 98 | "name": "PowerShell", 99 | "pygments_lexer": "powershell", 100 | "version": "7.0" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 4 105 | } 106 | -------------------------------------------------------------------------------- /13_twelve_days/twelve_days.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | [ValidateRange(1, 12)] 18 | [int]$num = 12, 19 | $outFile 20 | ) 21 | 22 | function verse { 23 | param($day) 24 | 25 | $ordinal = 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 26 | 'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth' 27 | 28 | $gifts = 'A partridge in a pear tree.', 29 | 'Two turtle doves,', 30 | 'Three French hens,', 31 | 'Four calling birds,', 32 | 'Five gold rings,', 33 | 'Six geese a laying,', 34 | 'Seven swans a swimming,', 35 | 'Eight maids a milking,', 36 | 'Nine ladies dancing,', 37 | 'Ten lords a leaping,', 38 | 'Eleven pipers piping,', 39 | 'Twelve drummers drumming,' 40 | 41 | $lines = @( 42 | "On the $($ordinal[$day]) day of Christmas,", 43 | 'My true love gave to me,' 44 | ) 45 | 46 | $reversedGifts = $gifts[0..$day] 47 | [array]::Reverse($reversedGifts) 48 | $lines += $reversedGifts 49 | 50 | if ($day -ge 1) { 51 | $lines[-1] = 'And ' + $lines[-1].ToLower() 52 | } 53 | 54 | $lines 55 | } 56 | 57 | $result = 0..($num - 1) | ForEach-Object { 58 | verse $_ 59 | } 60 | 61 | if ($outFile) { 62 | $result | Set-Content $outFile 63 | } 64 | else { 65 | $result -join "`r`n" 66 | } 67 | -------------------------------------------------------------------------------- /14_rhymer/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/14_rhymer/AllTest.ps1 -------------------------------------------------------------------------------- /14_rhymer/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/14_rhymer/README.md -------------------------------------------------------------------------------- /14_rhymer/rhymer.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Rhymer\n", 8 | "\n", 9 | "Write a program that will create rhyming words for a given word by removing the initial consonant sounds and substituting other sounds.\n", 10 | "\n", 11 | "Note that the given word should not appear in the output, so \"cake\" will be omitted from this run\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "metadata": { 18 | "dotnet_interactive": { 19 | "language": "pwsh" 20 | }, 21 | "polyglot_notebook": { 22 | "kernelName": "pwsh" 23 | }, 24 | "vscode": { 25 | "languageId": "polyglot-notebook" 26 | } 27 | }, 28 | "outputs": [ 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "bake\n", 34 | "blake\n", 35 | "brake\n", 36 | "chake\n", 37 | "clake\n", 38 | "crake\n", 39 | "dake\n", 40 | "drake\n", 41 | "fake\n", 42 | "flake\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "./rhymer.ps1 cake | Select-Object -First 10" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "The output should be sorted alphabetically.\n", 55 | "\n", 56 | "If there is no initial consonant sound, then apply all the consonant sounds to the given word" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 2, 62 | "metadata": { 63 | "dotnet_interactive": { 64 | "language": "pwsh" 65 | }, 66 | "polyglot_notebook": { 67 | "kernelName": "pwsh" 68 | }, 69 | "vscode": { 70 | "languageId": "polyglot-notebook" 71 | } 72 | }, 73 | "outputs": [ 74 | { 75 | "name": "stdout", 76 | "output_type": "stream", 77 | "text": [ 78 | "thwapple\n", 79 | "trapple\n", 80 | "twapple\n", 81 | "vapple\n", 82 | "wapple\n", 83 | "whapple\n", 84 | "wrapple\n", 85 | "xapple\n", 86 | "yapple\n", 87 | "zapple\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "./rhymer.ps1 apple | Select-Object -last 10" 93 | ] 94 | } 95 | ], 96 | "metadata": { 97 | "kernelspec": { 98 | "display_name": ".NET (PowerShell)", 99 | "language": "PowerShell", 100 | "name": ".net-powershell" 101 | }, 102 | "language_info": { 103 | "file_extension": ".ps1", 104 | "mimetype": "text/x-powershell", 105 | "name": "PowerShell", 106 | "pygments_lexer": "powershell", 107 | "version": "7.0" 108 | } 109 | }, 110 | "nbformat": 4, 111 | "nbformat_minor": 4 112 | } 113 | -------------------------------------------------------------------------------- /14_rhymer/rhymer.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $word 18 | ) 19 | 20 | function Invoke-Stemmer { 21 | param($word) 22 | 23 | $word = $word.ToLower() 24 | 25 | $vowelPos = $(foreach ($vowel in 'aeiou'.ToCharArray()) { 26 | $word.IndexOf($vowel) 27 | }).Where( { $_ -gt -1 }) 28 | 29 | if ($vowelPos) { 30 | $firstVowel = ($vowelPos | Measure-Object -Minimum).Minimum 31 | 32 | $word.Substring(0, $firstVowel) 33 | $word.Substring($firstVowel) 34 | } 35 | else { 36 | $word 37 | } 38 | } 39 | 40 | if ($word) { 41 | [string[]]$prefixes = 'bcdfghjklmnpqrstvwxyz'.ToCharArray() + $( 42 | 'bl br ch cl cr dr fl fr gl gr pl pr sc' 43 | 'sh sk sl sm sn sp st sw th tr tw thw wh wr' 44 | 'sch scr shr sph spl spr squ str thr' 45 | ).split() 46 | 47 | $start, $rest = Invoke-Stemmer $word 48 | 49 | if ($rest) { 50 | $(foreach ($p in $prefixes.where( { $_ -ne $start } )) { 51 | $p + $rest 52 | }) | Sort-Object 53 | } 54 | else { 55 | "Cannot rhyme '$word'" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /14_rhymer/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $word 18 | ) 19 | 20 | function Invoke-Stemmer { 21 | param($word) 22 | 23 | $word = $word.ToLower() 24 | 25 | $vowelPos = $(foreach ($vowel in 'aeiou'.ToCharArray()) { 26 | $word.IndexOf($vowel) 27 | }).Where( { $_ -gt -1 }) 28 | 29 | if ($vowelPos) { 30 | $firstVowel = ($vowelPos | Measure-Object -Minimum).Minimum 31 | 32 | $word.Substring(0, $firstVowel) 33 | $word.Substring($firstVowel) 34 | } 35 | else { 36 | $word 37 | } 38 | } 39 | 40 | if ($word) { 41 | [string[]]$prefixes = 'bcdfghjklmnpqrstvwxyz'.ToCharArray() + $( 42 | 'bl br ch cl cr dr fl fr gl gr pl pr sc' 43 | 'sh sk sl sm sn sp st sw th tr tw thw wh wr' 44 | 'sch scr shr sph spl spr squ str thr' 45 | ).split() 46 | 47 | $start, $rest = Invoke-Stemmer $word 48 | 49 | if ($rest) { 50 | $(foreach ($p in $prefixes.where( { $_ -ne $start } )) { 51 | $p + $rest 52 | }) | Sort-Object 53 | } 54 | else { 55 | "Cannot rhyme '$word'" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /14_rhymer/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/14_rhymer/test.ps1 -------------------------------------------------------------------------------- /15_kentucky_friar/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/15_kentucky_friar/AllTest.ps1 -------------------------------------------------------------------------------- /15_kentucky_friar/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/15_kentucky_friar/README.md -------------------------------------------------------------------------------- /15_kentucky_friar/friar.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# The Kentucky Friar\n", 8 | "\n", 9 | "Write a program that will drop the final \"g\" of two-syllable words ending in \"-ing\" and also replace any occurrence of the word \"you\" (case-insensitive) with the word \"y'all\" so as to transform text into a dialect common to the US Deep South (from which your author hails).\n", 10 | "\n", 11 | "The given text may come from the command line" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "metadata": { 18 | "dotnet_interactive": { 19 | "language": "pwsh" 20 | }, 21 | "polyglot_notebook": { 22 | "kernelName": "pwsh" 23 | }, 24 | "vscode": { 25 | "languageId": "polyglot-notebook" 26 | } 27 | }, 28 | "outputs": [ 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "y'all cookin'\r\n" 34 | ] 35 | } 36 | ], 37 | "source": [ 38 | "./friar.ps1 'Do you want to do some cooking with me?'" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "Or from an input file" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 2, 51 | "metadata": { 52 | "dotnet_interactive": { 53 | "language": "pwsh" 54 | }, 55 | "polyglot_notebook": { 56 | "kernelName": "pwsh" 57 | }, 58 | "vscode": { 59 | "languageId": "polyglot-notebook" 60 | } 61 | }, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "y'all y'all y'all admirin'\r\n" 68 | ] 69 | } 70 | ], 71 | "source": [ 72 | "./friar.ps1 ../inputFiles/nobody.txt" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": {}, 78 | "source": [ 79 | "Note that one-syllable words ending with \"-ing\" should be unchanged" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 3, 85 | "metadata": { 86 | "dotnet_interactive": { 87 | "language": "pwsh" 88 | }, 89 | "polyglot_notebook": { 90 | "kernelName": "pwsh" 91 | }, 92 | "vscode": { 93 | "languageId": "polyglot-notebook" 94 | } 95 | }, 96 | "outputs": [ 97 | { 98 | "name": "stdout", 99 | "output_type": "stream", 100 | "text": [ 101 | "swing\r\n" 102 | ] 103 | } 104 | ], 105 | "source": [ 106 | "./friar.ps1 swing" 107 | ] 108 | } 109 | ], 110 | "metadata": { 111 | "kernelspec": { 112 | "display_name": ".NET (PowerShell)", 113 | "language": "PowerShell", 114 | "name": ".net-powershell" 115 | }, 116 | "language_info": { 117 | "file_extension": ".ps1", 118 | "mimetype": "text/x-powershell", 119 | "name": "PowerShell", 120 | "pygments_lexer": "powershell", 121 | "version": "7.0" 122 | } 123 | }, 124 | "nbformat": 4, 125 | "nbformat_minor": 4 126 | } 127 | -------------------------------------------------------------------------------- /15_kentucky_friar/friar.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $text 18 | ) 19 | 20 | function Invoke-Fry { 21 | param($word) 22 | 23 | if ($word.ToLower() -eq 'you') { 24 | $word[0] + "'all" 25 | } 26 | 27 | if ($word.EndsWith('ing')) { 28 | if ($word.Substring(0, ($word.Length - 3)).IndexOfAny('AaEeIiOoUuYy'.ToCharArray()) -gt -1) { 29 | $word.Substring(0, ($word.Length - 1)) + "'" 30 | } 31 | else { 32 | $word 33 | } 34 | } 35 | } 36 | 37 | if (Test-Path $text -ErrorAction SilentlyContinue) { 38 | $text = Get-Content $text 39 | } 40 | 41 | $(foreach ($line in $text.Split("`n")) { 42 | foreach ($word in [regex]::Split($line.Trim(), '\W+')) { 43 | Invoke-Fry $word 44 | } 45 | }) -join ' ' 46 | -------------------------------------------------------------------------------- /15_kentucky_friar/inputs/banner.txt: -------------------------------------------------------------------------------- 1 | O! Say, can you see, by the dawn's early light, 2 | What so proudly we hailed at the twilight's last gleaming - 3 | Whose broad stripes and bright stars, through the clouds of the fight, 4 | O'er the ramparts we watched were so gallantly streaming? 5 | And the rockets' red glare, the bombs bursting in air, 6 | Gave proof through the night that our flag was still there; 7 | O! say, does that star-spangled banner yet wave 8 | O'er the land of the free and the home of the brave? 9 | -------------------------------------------------------------------------------- /15_kentucky_friar/inputs/blake.txt: -------------------------------------------------------------------------------- 1 | Father, father, where are you going? 2 | Oh do not walk so fast! 3 | Speak, father, speak to your little boy, 4 | Or else I shall be lost. 5 | -------------------------------------------------------------------------------- /15_kentucky_friar/inputs/dickinson.txt: -------------------------------------------------------------------------------- 1 | Much madness is divinest sense 2 | To a discerning eye; 3 | Much sense the starkest madness. 4 | 'T is the majority 5 | In this, as all, prevails. 6 | Assent, and you are sane; 7 | Demur, — you're straightway dangerous, 8 | And handled with a chain. 9 | -------------------------------------------------------------------------------- /15_kentucky_friar/inputs/raven.txt: -------------------------------------------------------------------------------- 1 | Presently my soul grew stronger; hesitating then no longer, 2 | "Sir," said I, "or Madam, truly your forgiveness I implore; 3 | But the fact is I was napping, and so gently you came rapping, 4 | And so faintly you came tapping, tapping at my chamber door, 5 | That I scarce was sure I heard you" - here I opened wide the door: - 6 | Darkness there and nothing more. 7 | -------------------------------------------------------------------------------- /15_kentucky_friar/inputs/shakespeare.txt: -------------------------------------------------------------------------------- 1 | I never saw that you did painting need, 2 | And therefore to your fair no painting set; 3 | I found, or thought I found, you did exceed 4 | That barren tender of a poet's debt: 5 | And therefore have I slept in your report, 6 | That you yourself, being extant, well might show 7 | How far a modern quill doth come too short, 8 | Speaking of worth, what worth in you doth grow. 9 | This silence for my sin you did impute, 10 | Which shall be most my glory being dumb; 11 | For I impair not beauty being mute, 12 | When others would give life, and bring a tomb. 13 | There lives more life in one of your fair eyes 14 | Than both your poets can in praise devise. 15 | -------------------------------------------------------------------------------- /15_kentucky_friar/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $text 18 | ) 19 | 20 | function Invoke-Fry { 21 | param($word) 22 | 23 | if ($word.ToLower() -eq 'you') { 24 | $word[0] + "'all" 25 | } 26 | 27 | if ($word.EndsWith('ing')) { 28 | if ($word.Substring(0, ($word.Length - 3)).IndexOfAny('AaEeIiOoUuYy'.ToCharArray()) -gt -1) { 29 | $word.Substring(0, ($word.Length - 1)) + "'" 30 | } 31 | else { 32 | $word 33 | } 34 | } 35 | } 36 | 37 | if (Test-Path $text -ErrorAction SilentlyContinue) { 38 | $text = Get-Content $text 39 | } 40 | 41 | $(foreach ($line in $text.Split("`n")) { 42 | foreach ($word in [regex]::Split($line.Trim(), '\W+')) { 43 | Invoke-Fry $word 44 | } 45 | }) -join ' ' 46 | -------------------------------------------------------------------------------- /15_kentucky_friar/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/15_kentucky_friar/test.ps1 -------------------------------------------------------------------------------- /16_scrambler/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/16_scrambler/AllTest.ps1 -------------------------------------------------------------------------------- /16_scrambler/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/16_scrambler/README.md -------------------------------------------------------------------------------- /16_scrambler/scrambler.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Scrambler\n", 8 | "\n", 9 | "Write a program that will randomly scramble the middle parts of words of 3 letters or more in a given text which may come from the command line" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "The qucik bwron fox jmups oevr the lzay dog.\r\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | "./scrambler.ps1 'The quick brown fox jumps over the lazy dog.'" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "Or from an input file" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "metadata": { 50 | "dotnet_interactive": { 51 | "language": "pwsh" 52 | }, 53 | "polyglot_notebook": { 54 | "kernelName": "pwsh" 55 | }, 56 | "vscode": { 57 | "languageId": "polyglot-notebook" 58 | } 59 | }, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "..\\iuFniletps\\fox.txt\r\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "./scrambler.ps1 ..\\inputFiles\\fox.txt" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "The program should accept a `-s` or `--seed` value for the random seed to ensure reproducibility" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 3, 83 | "metadata": { 84 | "dotnet_interactive": { 85 | "language": "pwsh" 86 | }, 87 | "polyglot_notebook": { 88 | "kernelName": "pwsh" 89 | }, 90 | "vscode": { 91 | "languageId": "polyglot-notebook" 92 | } 93 | }, 94 | "outputs": [ 95 | { 96 | "name": "stdout", 97 | "output_type": "stream", 98 | "text": [ 99 | "../ielFntupis/fox.txt\r\n" 100 | ] 101 | } 102 | ], 103 | "source": [ 104 | "./scrambler.ps1 -s 1 ../inputFiles/fox.txt" 105 | ] 106 | } 107 | ], 108 | "metadata": { 109 | "kernelspec": { 110 | "display_name": ".NET (PowerShell)", 111 | "language": "PowerShell", 112 | "name": ".net-powershell" 113 | }, 114 | "language_info": { 115 | "file_extension": ".ps1", 116 | "mimetype": "text/x-powershell", 117 | "name": "PowerShell", 118 | "pygments_lexer": "powershell", 119 | "version": "7.0" 120 | } 121 | }, 122 | "nbformat": 4, 123 | "nbformat_minor": 4 124 | } 125 | -------------------------------------------------------------------------------- /16_scrambler/scrambler.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $text, 18 | $seed 19 | ) 20 | 21 | function Invoke-Scramble { 22 | param($word) 23 | 24 | if ($word.Length -gt 3 -and [regex]::match($word, "\w+")) { 25 | $middle = $word.Substring(1, $word.Length - 2) 26 | $random = $middle.ToCharArray() | Sort-Object { Get-Random } 27 | 28 | $word[0] + (-join $random) + $word[-1] 29 | } 30 | else { 31 | $word 32 | } 33 | } 34 | 35 | if ($seed) { $null = Get-Random -SetSeed $seed } 36 | 37 | $pattern = "([a-zA-Z](?:[a-zA-Z']*[a-zA-Z])?)" 38 | 39 | -join $(foreach ($word in [regex]::Split($text, $pattern)) { 40 | Invoke-Scramble $word 41 | }) 42 | -------------------------------------------------------------------------------- /16_scrambler/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $text, 18 | $seed 19 | ) 20 | 21 | function Invoke-Scramble { 22 | param($word) 23 | 24 | if ($word.Length -gt 3 -and [regex]::match($word, "\w+")) { 25 | $middle = $word.Substring(1, $word.Length - 2) 26 | $random = $middle.ToCharArray() | Sort-Object { Get-Random } 27 | 28 | $word[0] + (-join $random) + $word[-1] 29 | } 30 | else { 31 | $word 32 | } 33 | } 34 | 35 | if ($seed) { $null = Get-Random -SetSeed $seed } 36 | 37 | $pattern = "([a-zA-Z](?:[a-zA-Z']*[a-zA-Z])?)" 38 | 39 | -join $(foreach ($word in [regex]::Split($text, $pattern)) { 40 | Invoke-Scramble $word 41 | }) 42 | -------------------------------------------------------------------------------- /16_scrambler/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/16_scrambler/test.ps1 -------------------------------------------------------------------------------- /17_mad_libs/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/17_mad_libs/AllTest.ps1 -------------------------------------------------------------------------------- /17_mad_libs/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/17_mad_libs/README.md -------------------------------------------------------------------------------- /17_mad_libs/inputs/fox.txt: -------------------------------------------------------------------------------- 1 | The quick jumps the lazy . -------------------------------------------------------------------------------- /17_mad_libs/mad.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Mad Libs\n", 8 | "\n", 9 | "Write a \"Mad Libs\" program that will read a given file and prompt the user for the parts of speech indicated in angle brackets, e.g., ``, replacing those values and printing the new text a la the beloved \"Mad Libs\" game." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "The quick surly car jumps under the lazy bicycle.\r\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | "./mad.ps1 ./inputs/fox.txt -i surly, car, under, bicycle" 37 | ] 38 | } 39 | ], 40 | "metadata": { 41 | "kernelspec": { 42 | "display_name": ".NET (PowerShell)", 43 | "language": "PowerShell", 44 | "name": ".net-powershell" 45 | }, 46 | "language_info": { 47 | "file_extension": ".ps1", 48 | "mimetype": "text/x-powershell", 49 | "name": "PowerShell", 50 | "pygments_lexer": "powershell", 51 | "version": "7.0" 52 | } 53 | }, 54 | "nbformat": 4, 55 | "nbformat_minor": 4 56 | } 57 | -------------------------------------------------------------------------------- /17_mad_libs/mad.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $file, 18 | [System.Collections.ArrayList]$inputs 19 | ) 20 | 21 | function Find-Brackets { 22 | param( 23 | $text 24 | ) 25 | 26 | $start = $text.IndexOf('<') 27 | $stop = $text.IndexOf('>') 28 | 29 | if ($start -ge 0 -and $stop -ge 0) { 30 | return $start, $stop 31 | } 32 | } 33 | 34 | $text = Get-Content -Raw $file 35 | $hadPlaceholders = $false 36 | 37 | while ($true) { 38 | $brackets = Find-Brackets $text 39 | 40 | if (!$brackets) { 41 | break 42 | } 43 | 44 | $start, $stop = $brackets 45 | 46 | $placeholder = -join $text[$start..($stop - 1)] 47 | $pos = $placeholder.Substring(1, ($placeholder.Length - 1)) 48 | 49 | $answer = $inputs[0] 50 | $inputs.RemoveAt(0) 51 | 52 | $text = (-join $text[0..($start - 1)]) + $answer + (-join $text[($stop + 1)..$text.Length]) 53 | 54 | $hadPlaceholders = $true 55 | } 56 | 57 | if ($hadPlaceholders) { 58 | $text 59 | } 60 | else { 61 | "$($file) has no placeholders." 62 | } -------------------------------------------------------------------------------- /17_mad_libs/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $file, 18 | [System.Collections.ArrayList]$inputs 19 | ) 20 | 21 | function Find-Brackets { 22 | param( 23 | $text 24 | ) 25 | 26 | $start = $text.IndexOf('<') 27 | $stop = $text.IndexOf('>') 28 | 29 | if ($start -ge 0 -and $stop -ge 0) { 30 | return $start, $stop 31 | } 32 | } 33 | 34 | $text = Get-Content -Raw $file 35 | $hadPlaceholders = $false 36 | 37 | while ($true) { 38 | $brackets = Find-Brackets $text 39 | 40 | if (!$brackets) { 41 | break 42 | } 43 | 44 | $start, $stop = $brackets 45 | 46 | $placeholder = -join $text[$start..($stop - 1)] 47 | $pos = $placeholder.Substring(1, ($placeholder.Length - 1)) 48 | 49 | $answer = $inputs[0] 50 | $inputs.RemoveAt(0) 51 | 52 | $text = (-join $text[0..($start - 1)]) + $answer + (-join $text[($stop + 1)..$text.Length]) 53 | 54 | $hadPlaceholders = $true 55 | } 56 | 57 | if ($hadPlaceholders) { 58 | $text 59 | } 60 | else { 61 | "$($file) has no placeholders." 62 | } -------------------------------------------------------------------------------- /17_mad_libs/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/17_mad_libs/test.ps1 -------------------------------------------------------------------------------- /18_gematria/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/18_gematria/AllTest.ps1 -------------------------------------------------------------------------------- /18_gematria/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/18_gematria/README.md -------------------------------------------------------------------------------- /18_gematria/gematria.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Gematria\n", 8 | "\n", 9 | "Write a program that will encode each word of a given text by summing the ASCII values of the characters." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [], 27 | "source": [ 28 | "# Source the powershell file\n", 29 | ". .\\gematria.ps1" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "The text may come from the command line" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 2, 42 | "metadata": { 43 | "dotnet_interactive": { 44 | "language": "pwsh" 45 | }, 46 | "polyglot_notebook": { 47 | "kernelName": "pwsh" 48 | }, 49 | "vscode": { 50 | "languageId": "polyglot-notebook" 51 | } 52 | }, 53 | "outputs": [ 54 | { 55 | "name": "stdout", 56 | "output_type": "stream", 57 | "text": [ 58 | "289 541 552 333 559 444 321 448 314\r\n" 59 | ] 60 | } 61 | ], 62 | "source": [ 63 | "Invoke-Gematria 'The quick brown fox jumps over the lazy dog.'" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "Or from an input file" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 3, 76 | "metadata": { 77 | "dotnet_interactive": { 78 | "language": "pwsh" 79 | }, 80 | "polyglot_notebook": { 81 | "kernelName": "pwsh" 82 | }, 83 | "vscode": { 84 | "languageId": "polyglot-notebook" 85 | } 86 | }, 87 | "outputs": [ 88 | { 89 | "name": "stdout", 90 | "output_type": "stream", 91 | "text": [ 92 | "289 541 552 333 559 444 321 448 314\r\n" 93 | ] 94 | } 95 | ], 96 | "source": [ 97 | "Invoke-Gematria ../inputFiles/fox.txt" 98 | ] 99 | } 100 | ], 101 | "metadata": { 102 | "kernelspec": { 103 | "display_name": ".NET (PowerShell)", 104 | "language": "PowerShell", 105 | "name": ".net-powershell" 106 | }, 107 | "language_info": { 108 | "file_extension": ".ps1", 109 | "mimetype": "text/x-powershell", 110 | "name": "PowerShell", 111 | "pygments_lexer": "powershell", 112 | "version": "7.0" 113 | } 114 | }, 115 | "nbformat": 4, 116 | "nbformat_minor": 4 117 | } 118 | -------------------------------------------------------------------------------- /18_gematria/gematria.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-Word2num { 2 | param( 3 | $word 4 | ) 5 | 6 | $word = $word -replace '[^A-Za-z0-9]', '' 7 | 8 | $word.ToCharArray() | 9 | ForEach-Object { $sum = 0 } { $sum += [int]$_ } { $sum } 10 | } 11 | 12 | function Invoke-Gematria { 13 | param( 14 | $word 15 | ) 16 | 17 | if (Test-Path $word) { 18 | $word = Get-Content $word 19 | } 20 | 21 | foreach ($line in $word) { 22 | $(foreach ($targetWord in $line.Split()) { 23 | Invoke-Word2num $targetWord 24 | }) -join ' ' 25 | } 26 | } -------------------------------------------------------------------------------- /18_gematria/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | function Invoke-Word2num { 17 | param( 18 | $word 19 | ) 20 | 21 | $word = $word -replace '[^A-Za-z0-9]', '' 22 | 23 | $sum = 0 24 | foreach ($char in $word.ToCharArray()) { 25 | $sum += [int]$char 26 | } 27 | $sum 28 | } 29 | 30 | function Invoke-Gematria { 31 | param( 32 | $word 33 | ) 34 | 35 | if (Test-Path $word) { 36 | $word = Get-Content $word 37 | } 38 | 39 | foreach ($line in $word) { 40 | $(foreach ($targetWord in $line.Split()) { 41 | Invoke-Word2num $targetWord 42 | }) -join ' ' 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /18_gematria/solution2-foreach-pipe.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-Word2num { 2 | param( 3 | $word 4 | ) 5 | 6 | $word = $word -replace '[^A-Za-z0-9]', '' 7 | 8 | $word.ToCharArray() | 9 | ForEach-Object { $sum = 0 } { $sum += [int]$_ } { $sum } 10 | } 11 | 12 | function Invoke-Gematria { 13 | param( 14 | $word 15 | ) 16 | 17 | if (Test-Path $word) { 18 | $word = Get-Content $word 19 | } 20 | 21 | foreach ($line in $word) { 22 | $(foreach ($targetWord in $line.Split()) { 23 | Invoke-Word2num $targetWord 24 | }) -join ' ' 25 | } 26 | } -------------------------------------------------------------------------------- /18_gematria/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/18_gematria/test.ps1 -------------------------------------------------------------------------------- /19_wod/19_wod.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | $file, 3 | $seed, 4 | $num, 5 | $easy 6 | ) 7 | 8 | if ($seed) { $null = Get-Random -SetSeed $seed } 9 | 10 | -------------------------------------------------------------------------------- /19_wod/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/19_wod/AllTest.ps1 -------------------------------------------------------------------------------- /19_wod/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/19_wod/README.md -------------------------------------------------------------------------------- /19_wod/inputs/bad-delimiter.tab: -------------------------------------------------------------------------------- 1 | exercise reps 2 | Burpees 20-50 3 | Situps 40-100 4 | Pushups 25-75 5 | Squats 20-50 6 | Pullups 10-30 7 | Hand-stand pushups 5-20 8 | Lunges 20-40 9 | Plank 30-60 10 | Crunches 20-30 11 | -------------------------------------------------------------------------------- /19_wod/inputs/bad-empty.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/19_wod/inputs/bad-empty.csv -------------------------------------------------------------------------------- /19_wod/inputs/bad-headers-only.csv: -------------------------------------------------------------------------------- 1 | exercise,reps 2 | -------------------------------------------------------------------------------- /19_wod/inputs/bad-headers.csv: -------------------------------------------------------------------------------- 1 | Exercise,Reps 2 | Burpees,200 3 | Situps,40.5-100 4 | Pushups,five-fifty 5 | Squats, 6 | Pullups,NA 7 | -------------------------------------------------------------------------------- /19_wod/inputs/bad-reps.csv: -------------------------------------------------------------------------------- 1 | exercise,reps 2 | Burpees,200 3 | Situps,40.5-100 4 | Pushups,five-fifty 5 | Squats, 6 | Pullups,NA 7 | -------------------------------------------------------------------------------- /19_wod/inputs/exercises.csv: -------------------------------------------------------------------------------- 1 | exercise,reps 2 | Burpees,20-50 3 | Situps,40-100 4 | Pushups,25-75 5 | Squats,20-50 6 | Pullups,10-30 7 | Hand-stand pushups,5-20 8 | Lunges,20-40 9 | Plank,30-60 10 | Crunches,20-30 11 | -------------------------------------------------------------------------------- /19_wod/inputs/silly-exercises.csv: -------------------------------------------------------------------------------- 1 | exercise,reps 2 | Squatting Chinups,20-50 3 | Hanging Chads,40-100 4 | Red Barchettas,25-75 5 | Rock Squats,20-50 6 | Masochistic Eardowns,10-30 7 | Erstwhile Lunges,5-20 8 | Existential Earflaps,20-40 9 | -------------------------------------------------------------------------------- /19_wod/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $file = '.\inputs\exercises.csv', 18 | $seed, 19 | $num = 4, 20 | [Switch]$easy 21 | ) 22 | 23 | Import-Module ..\UtilityModules\UtilityModules.psm1 24 | 25 | if ($seed) { $null = Get-Random -SetSeed $seed } 26 | 27 | $exercises = $(foreach ($record in Import-Csv $file) { 28 | [int]$low, [int]$high = $record.reps.split('-') 29 | [int]$reps = Get-Random -Minimum $low -Maximum ($high + 1) 30 | 31 | if ($easy) { 32 | $reps /= 2 33 | } 34 | 35 | [PSCustomObject]@{ 36 | Exercise = $record.exercise 37 | Reps = $reps 38 | } 39 | }) 40 | 41 | Get-RandomSample $exercises $num 42 | -------------------------------------------------------------------------------- /19_wod/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/19_wod/test.ps1 -------------------------------------------------------------------------------- /19_wod/wod.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# WOD (Workout of the Day)\n", 8 | "\n", 9 | "Create a program that will read a CSV `-f` or `-file` of exercises (default `exercises.csv`) and create a Workout of the Day" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "dotnet_interactive": { 17 | "language": "pwsh" 18 | }, 19 | "polyglot_notebook": { 20 | "kernelName": "pwsh" 21 | }, 22 | "vscode": { 23 | "languageId": "polyglot-notebook" 24 | } 25 | }, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "\n", 32 | "\u001b[32;1mExercise Reps\u001b[0m\n", 33 | "\u001b[32;1m-------- ----\u001b[0m\n", 34 | "Lunges 28\n", 35 | "Pullups 21\n", 36 | "Crunches 30\n", 37 | "Plank 43\n", 38 | "\n" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "./wod.ps1 -s 2" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "The program should accept an alternate `-file`" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 2, 56 | "metadata": { 57 | "dotnet_interactive": { 58 | "language": "pwsh" 59 | }, 60 | "polyglot_notebook": { 61 | "kernelName": "pwsh" 62 | }, 63 | "vscode": { 64 | "languageId": "polyglot-notebook" 65 | } 66 | }, 67 | "outputs": [ 68 | { 69 | "name": "stdout", 70 | "output_type": "stream", 71 | "text": [ 72 | "\n", 73 | "\u001b[32;1mExercise Reps\u001b[0m\n", 74 | "\u001b[32;1m-------- ----\u001b[0m\n", 75 | "Rock Squats 32\n", 76 | "Erstwhile Lunges 14\n", 77 | "Hanging Chads 73\n", 78 | "Masochistic Eardowns 15\n", 79 | "\n" 80 | ] 81 | } 82 | ], 83 | "source": [ 84 | "./wod.ps1 -f ./inputs/silly-exercises.csv -seed 1" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "The program should accept an `-n` or `-num` argument to control the number of exercises which are randomly chosen from the input file.\n", 92 | "\n", 93 | "The \"Reps\" value will be randomly chosen from the given low/high range in the \"reps\" column" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 3, 99 | "metadata": { 100 | "dotnet_interactive": { 101 | "language": "pwsh" 102 | }, 103 | "polyglot_notebook": { 104 | "kernelName": "pwsh" 105 | }, 106 | "vscode": { 107 | "languageId": "polyglot-notebook" 108 | } 109 | }, 110 | "outputs": [ 111 | { 112 | "name": "stdout", 113 | "output_type": "stream", 114 | "text": [ 115 | "\n", 116 | "\u001b[32;1mExercise Reps\u001b[0m\n", 117 | "\u001b[32;1m-------- ----\u001b[0m\n", 118 | "Squats 33\n", 119 | "Burpees 32\n", 120 | "\n" 121 | ] 122 | } 123 | ], 124 | "source": [ 125 | "./wod.ps1 -n 2" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": {}, 131 | "source": [ 132 | "The program should accept a `-s` or `-seed` value for the random seed to ensure reproducibility" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": 4, 138 | "metadata": { 139 | "dotnet_interactive": { 140 | "language": "pwsh" 141 | }, 142 | "polyglot_notebook": { 143 | "kernelName": "pwsh" 144 | }, 145 | "vscode": { 146 | "languageId": "polyglot-notebook" 147 | } 148 | }, 149 | "outputs": [ 150 | { 151 | "name": "stdout", 152 | "output_type": "stream", 153 | "text": [ 154 | "\n", 155 | "\u001b[32;1mExercise Reps\u001b[0m\n", 156 | "\u001b[32;1m-------- ----\u001b[0m\n", 157 | "Situps 73\n", 158 | "Burpees 28\n", 159 | "Hand-stand pushups 14\n", 160 | "Lunges 25\n", 161 | "\n" 162 | ] 163 | } 164 | ], 165 | "source": [ 166 | "./wod.ps1 -s 1" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": {}, 172 | "source": [ 173 | "As well as a `-e` or `-easy` flag to indicate that the reps should be halved" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 5, 179 | "metadata": { 180 | "dotnet_interactive": { 181 | "language": "pwsh" 182 | }, 183 | "polyglot_notebook": { 184 | "kernelName": "pwsh" 185 | }, 186 | "vscode": { 187 | "languageId": "polyglot-notebook" 188 | } 189 | }, 190 | "outputs": [ 191 | { 192 | "name": "stdout", 193 | "output_type": "stream", 194 | "text": [ 195 | "\n", 196 | "\u001b[32;1mExercise Reps\u001b[0m\n", 197 | "\u001b[32;1m-------- ----\u001b[0m\n", 198 | "Situps 36\n", 199 | "Burpees 14\n", 200 | "Hand-stand pushups 7\n", 201 | "Lunges 12\n", 202 | "\n" 203 | ] 204 | } 205 | ], 206 | "source": [ 207 | "./wod.ps1 -s 1 -e" 208 | ] 209 | } 210 | ], 211 | "metadata": { 212 | "kernelspec": { 213 | "display_name": ".NET (PowerShell)", 214 | "language": "PowerShell", 215 | "name": ".net-powershell" 216 | }, 217 | "language_info": { 218 | "file_extension": ".ps1", 219 | "mimetype": "text/x-powershell", 220 | "name": "PowerShell", 221 | "pygments_lexer": "powershell", 222 | "version": "7.0" 223 | } 224 | }, 225 | "nbformat": 4, 226 | "nbformat_minor": 4 227 | } 228 | -------------------------------------------------------------------------------- /19_wod/wod.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $file = '.\inputs\exercises.csv', 18 | $seed, 19 | $num = 4, 20 | [Switch]$easy 21 | ) 22 | 23 | Import-Module ..\UtilityModules\UtilityModules.psm1 24 | 25 | if ($seed) { $null = Get-Random -SetSeed $seed } 26 | 27 | $exercises = $(foreach ($record in Import-Csv $file) { 28 | [int]$low, [int]$high = $record.reps.split('-') 29 | [int]$reps = Get-Random -Minimum $low -Maximum ($high + 1) 30 | 31 | if ($easy) { 32 | $reps /= 2 33 | } 34 | 35 | [PSCustomObject]@{ 36 | Exercise = $record.exercise 37 | Reps = $reps 38 | } 39 | }) 40 | 41 | Get-RandomSample $exercises $num 42 | -------------------------------------------------------------------------------- /20_password/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/20_password/AllTest.ps1 -------------------------------------------------------------------------------- /20_password/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/20_password/README.md -------------------------------------------------------------------------------- /20_password/const/adjs.txt: -------------------------------------------------------------------------------- 1 | absent 2 | actual 3 | adjourn 4 | annotated 5 | appellate 6 | appropriate 7 | certain 8 | civil 9 | clear 10 | common 11 | compulsory 12 | criminal 13 | cruel 14 | current 15 | different 16 | direct 17 | disorderly 18 | distinct 19 | domestic 20 | due 21 | eligible 22 | equal 23 | excessive 24 | exclusive 25 | executive 26 | extraordinary 27 | first 28 | foreign 29 | fourth 30 | free 31 | general 32 | good 33 | great 34 | high 35 | imminent 36 | impartial 37 | indian 38 | infamous 39 | inferior 40 | inhabitant 41 | inoperative 42 | judicial 43 | just 44 | large 45 | least 46 | legislative 47 | liable 48 | limited 49 | long 50 | male 51 | more 52 | natural 53 | naval 54 | necessary 55 | needful 56 | net 57 | new 58 | next 59 | numerous 60 | open 61 | original 62 | other 63 | own 64 | particular 65 | perfect 66 | present 67 | principal 68 | private 69 | pro 70 | probable 71 | proper 72 | public 73 | regular 74 | religious 75 | republican 76 | respective 77 | same 78 | second 79 | secure 80 | several 81 | sixth 82 | small 83 | sole 84 | speedy 85 | square 86 | subject 87 | subsequent 88 | such 89 | sufficient 90 | supreme 91 | temporary 92 | third 93 | unable 94 | uncorrected 95 | uniform 96 | unreasonable 97 | unusual 98 | useful 99 | valid 100 | whole 101 | -------------------------------------------------------------------------------- /20_password/const/nouns.txt: -------------------------------------------------------------------------------- 1 | account 2 | affirmation 3 | age 4 | aid 5 | amendment 6 | appointment 7 | article 8 | attendance 9 | ballot 10 | case 11 | choice 12 | citizen 13 | claim 14 | compensation 15 | continuance 16 | crime 17 | date 18 | day 19 | death 20 | debt 21 | declaration 22 | defence 23 | disability 24 | dollar 25 | duty 26 | effect 27 | elect 28 | election 29 | elector 30 | enumeration 31 | execution 32 | executive 33 | fifth 34 | fourth 35 | herein 36 | importation 37 | insurrection 38 | jurisdiction 39 | jury 40 | land 41 | law 42 | legislation 43 | legislature 44 | life 45 | list 46 | majority 47 | manner 48 | meeting 49 | member 50 | money 51 | noon 52 | number 53 | objection 54 | offense 55 | office 56 | officer 57 | ordain 58 | order 59 | part 60 | people 61 | person 62 | power 63 | presence 64 | present 65 | privilege 66 | process 67 | property 68 | punishment 69 | purpose 70 | question 71 | quorum 72 | rebellion 73 | regulation 74 | representation 75 | representative 76 | requisite 77 | resignation 78 | right 79 | rule 80 | section 81 | senator 82 | service 83 | state 84 | subject 85 | submission 86 | tax 87 | tempore 88 | term 89 | thing 90 | third 91 | time 92 | trial 93 | vacancy 94 | version 95 | vote 96 | whereof 97 | witness 98 | writ 99 | writing 100 | year 101 | -------------------------------------------------------------------------------- /20_password/const/verbs.txt: -------------------------------------------------------------------------------- 1 | abridge 2 | accord 3 | act 4 | adjourn 5 | admit 6 | affect 7 | appoint 8 | apportion 9 | approve 10 | ascertain 11 | assemble 12 | attain 13 | authorize 14 | be 15 | bear 16 | become 17 | bind 18 | call 19 | choose 20 | commit 21 | compel 22 | compose 23 | consist 24 | constitute 25 | construe 26 | convict 27 | count 28 | declare 29 | deny 30 | determine 31 | devolve 32 | direct 33 | discharge 34 | divide 35 | do 36 | elect 37 | enforce 38 | enjoy 39 | enter 40 | entitle 41 | establish 42 | exceed 43 | except 44 | exclude 45 | execute 46 | exercise 47 | exist 48 | extend 49 | fill 50 | fix 51 | follow 52 | form 53 | give 54 | grant 55 | happen 56 | have 57 | hold 58 | include 59 | increase 60 | issue 61 | keep 62 | lay 63 | lie 64 | make 65 | may 66 | meet 67 | pass 68 | pay 69 | prescribe 70 | present 71 | prohibit 72 | promote 73 | propose 74 | provide 75 | publish 76 | punish 77 | qualify 78 | question 79 | ratify 80 | receive 81 | regulate 82 | remove 83 | repeal 84 | require 85 | return 86 | say 87 | secure 88 | shall 89 | sign 90 | sit 91 | support 92 | take 93 | tax 94 | think 95 | transmit 96 | try 97 | vest 98 | vote 99 | will 100 | write 101 | -------------------------------------------------------------------------------- /20_password/password.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Password\n", 8 | "\n", 9 | "https://xkcd.com/936/\n", 10 | "\n", 11 | "Create a program that will randomly combine words from given text(s) to create novel, memorable, unbreakable passwords.\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "metadata": { 18 | "dotnet_interactive": { 19 | "language": "pwsh" 20 | }, 21 | "polyglot_notebook": { 22 | "kernelName": "pwsh" 23 | }, 24 | "vscode": { 25 | "languageId": "polyglot-notebook" 26 | } 27 | }, 28 | "outputs": [ 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "FlumeLuciteHagletFaulty\n", 34 | "AbasManureNosismLuwian\n", 35 | "ProsoSimianSearArcady\n" 36 | ] 37 | } 38 | ], 39 | "source": [ 40 | "./password.ps1" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "Be sure to accept a `-s` or `--seed` option to use as the random seed to ensure reproducibility" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 3, 53 | "metadata": { 54 | "dotnet_interactive": { 55 | "language": "pwsh" 56 | }, 57 | "polyglot_notebook": { 58 | "kernelName": "pwsh" 59 | }, 60 | "vscode": { 61 | "languageId": "polyglot-notebook" 62 | } 63 | }, 64 | "outputs": [ 65 | { 66 | "name": "stdout", 67 | "output_type": "stream", 68 | "text": [ 69 | "SilkedDoneyKvassBird\n", 70 | "JewGoelViandPrase\n", 71 | "AlmaBerithDomettPitau\n" 72 | ] 73 | } 74 | ], 75 | "source": [ 76 | "./password.ps1 -s 1" 77 | ] 78 | } 79 | ], 80 | "metadata": { 81 | "kernelspec": { 82 | "display_name": ".NET (PowerShell)", 83 | "language": "PowerShell", 84 | "name": ".net-powershell" 85 | }, 86 | "language_info": { 87 | "file_extension": ".ps1", 88 | "mimetype": "text/x-powershell", 89 | "name": "PowerShell", 90 | "pygments_lexer": "powershell", 91 | "version": "7.0" 92 | } 93 | }, 94 | "nbformat": 4, 95 | "nbformat_minor": 4 96 | } 97 | -------------------------------------------------------------------------------- /20_password/password.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $file='../inputFiles/words.txt', 18 | $num = 3, 19 | $numWords = 4, 20 | $minWordLength = 3, 21 | $maxWordLength = 6, 22 | $seed = ([System.Environment]::TickCount), 23 | [Switch]$l33t 24 | ) 25 | 26 | function Get-Ransom { 27 | <# 28 | .Synopsis 29 | Randomly choose an upper or lowercase letter to return 30 | #> 31 | param( 32 | $text 33 | ) 34 | 35 | -join $( 36 | foreach ($c in $text.ToCharArray()) { 37 | if ((Get-Random -Minimum 0 -Maximum 2) -eq 1) { 38 | [char]::ToLower($c) 39 | } 40 | else { 41 | [char]::ToUpper($c) 42 | } 43 | } 44 | ) 45 | } 46 | 47 | Import-Module "$PSScriptRoot\..\UtilityModules\UtilityModules.psm1" 48 | 49 | $words = New-Object System.Collections.Generic.HashSet[string] 50 | $TextInfo = (Get-Culture).TextInfo 51 | 52 | foreach ($targetFile in $file) { 53 | $targetFile = Resolve-Path $targetFile 54 | foreach ($line in [System.IO.File]::ReadAllLines($targetFile)) { 55 | foreach ($word in ($line.ToLower().Split() -replace '[^a-zA-Z]', '' ).Where( { $_.Length -ge $minWordLength -and $_.Length -le $maxWordLength })) { 56 | $null = $words.Add($TextInfo.ToTitleCase($word)) 57 | } 58 | } 59 | } 60 | 61 | $words = $words | Sort-Object 62 | 63 | $totalWords = $words.Count 64 | $rnd = [Random]::new($seed) 65 | 66 | for ($i = 0; $i -lt $num; $i++) { 67 | $h = @{} 68 | do { 69 | $h.($words[$rnd.Next(0, $totalWords)]) = $null 70 | } until($h.Keys.Count -eq $numWords) 71 | 72 | -join $h.Keys 73 | } -------------------------------------------------------------------------------- /20_password/scarlet/adjs.txt: -------------------------------------------------------------------------------- 1 | alive 2 | awful 3 | bad 4 | beautiful 5 | bitter 6 | black 7 | bright 8 | calm 9 | certain 10 | close 11 | common 12 | conscious 13 | dark 14 | dead 15 | deep 16 | dreary 17 | early 18 | earthly 19 | evil 20 | fair 21 | familiar 22 | few 23 | first 24 | former 25 | free 26 | full 27 | good 28 | gray 29 | great 30 | guilty 31 | happy 32 | hard 33 | heavy 34 | high 35 | holy 36 | human 37 | kind 38 | large 39 | last 40 | latter 41 | least 42 | less 43 | like 44 | little 45 | lonely 46 | long 47 | many 48 | miserable 49 | moral 50 | more 51 | most 52 | much 53 | native 54 | natural 55 | new 56 | next 57 | old 58 | only 59 | open 60 | other 61 | outward 62 | own 63 | pale 64 | peculiar 65 | physical 66 | poor 67 | present 68 | professional 69 | public 70 | quiet 71 | real 72 | red 73 | rich 74 | sacred 75 | sad 76 | same 77 | scarlet 78 | secret 79 | sensitive 80 | short 81 | sinful 82 | singular 83 | small 84 | solemn 85 | spiritual 86 | stern 87 | strange 88 | strong 89 | such 90 | terrible 91 | true 92 | ugly 93 | venerable 94 | very 95 | well 96 | white 97 | whole 98 | wild 99 | wise 100 | young 101 | -------------------------------------------------------------------------------- /20_password/scarlet/nouns.txt: -------------------------------------------------------------------------------- 1 | age 2 | air 3 | arm 4 | art 5 | aspect 6 | bosom 7 | breast 8 | brook 9 | character 10 | child 11 | church 12 | clergyman 13 | crowd 14 | day 15 | death 16 | door 17 | earth 18 | evil 19 | expression 20 | eye 21 | face 22 | father 23 | figure 24 | forest 25 | friend 26 | hand 27 | hath 28 | head 29 | heart 30 | hour 31 | house 32 | idea 33 | impulse 34 | infant 35 | iron 36 | kind 37 | law 38 | letter 39 | life 40 | light 41 | look 42 | magistrate 43 | man 44 | market 45 | matter 46 | mind 47 | minister 48 | moment 49 | mother 50 | name 51 | nature 52 | night 53 | nothing 54 | object 55 | one 56 | pain 57 | part 58 | passion 59 | people 60 | person 61 | physician 62 | place 63 | point 64 | power 65 | prison 66 | purpose 67 | scaffold 68 | scene 69 | secret 70 | self 71 | shadow 72 | shame 73 | side 74 | sin 75 | smile 76 | something 77 | sorrow 78 | soul 79 | spirit 80 | state 81 | step 82 | street 83 | sunshine 84 | sympathy 85 | thing 86 | thou 87 | thought 88 | time 89 | token 90 | town 91 | tree 92 | truth 93 | voice 94 | way 95 | window 96 | woman 97 | word 98 | world 99 | year 100 | “ 101 | -------------------------------------------------------------------------------- /20_password/scarlet/verbs.txt: -------------------------------------------------------------------------------- 1 | answer 2 | appear 3 | approach 4 | ask 5 | be 6 | bear 7 | become 8 | begin 9 | behold 10 | believe 11 | break 12 | bring 13 | burn 14 | call 15 | can 16 | cast 17 | catch 18 | come 19 | continue 20 | could 21 | cover 22 | cry 23 | deem 24 | die 25 | discern 26 | do 27 | draw 28 | embroider 29 | enter 30 | fall 31 | feel 32 | find 33 | gather 34 | gaze 35 | give 36 | go 37 | grow 38 | have 39 | hear 40 | hide 41 | hold 42 | imagine 43 | keep 44 | know 45 | laugh 46 | lay 47 | lead 48 | learn 49 | leave 50 | let 51 | lie 52 | live 53 | look 54 | lose 55 | love 56 | make 57 | may 58 | mean 59 | meet 60 | must 61 | need 62 | offer 63 | pass 64 | play 65 | possess 66 | put 67 | recognize 68 | remain 69 | reply 70 | reveal 71 | rise 72 | run 73 | save 74 | say 75 | see 76 | seek 77 | seem 78 | set 79 | shall 80 | should 81 | show 82 | sit 83 | smile 84 | speak 85 | stand 86 | take 87 | talk 88 | teach 89 | tell 90 | think 91 | throw 92 | touch 93 | turn 94 | walk 95 | wear 96 | whisper 97 | will 98 | win 99 | work 100 | would 101 | -------------------------------------------------------------------------------- /20_password/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $file='../inputFiles/words.txt', 18 | $num = 3, 19 | $numWords = 4, 20 | $minWordLength = 3, 21 | $maxWordLength = 6, 22 | $seed = ([System.Environment]::TickCount), 23 | [Switch]$l33t 24 | ) 25 | 26 | function Get-Ransom { 27 | <# 28 | .Synopsis 29 | Randomly choose an upper or lowercase letter to return 30 | #> 31 | param( 32 | $text 33 | ) 34 | 35 | -join $( 36 | foreach ($c in $text.ToCharArray()) { 37 | if ((Get-Random -Minimum 0 -Maximum 2) -eq 1) { 38 | [char]::ToLower($c) 39 | } 40 | else { 41 | [char]::ToUpper($c) 42 | } 43 | } 44 | ) 45 | } 46 | 47 | Import-Module "$PSScriptRoot\..\UtilityModules\UtilityModules.psm1" 48 | 49 | $words = New-Object System.Collections.Generic.HashSet[string] 50 | $TextInfo = (Get-Culture).TextInfo 51 | 52 | foreach ($targetFile in $file) { 53 | $targetFile = Resolve-Path $targetFile 54 | foreach ($line in [System.IO.File]::ReadAllLines($targetFile)) { 55 | foreach ($word in ($line.ToLower().Split() -replace '[^a-zA-Z]', '' ).Where( { $_.Length -ge $minWordLength -and $_.Length -le $maxWordLength })) { 56 | $null = $words.Add($TextInfo.ToTitleCase($word)) 57 | } 58 | } 59 | } 60 | 61 | $words = $words | Sort-Object 62 | 63 | $totalWords = $words.Count 64 | $rnd = [Random]::new($seed) 65 | 66 | for ($i = 0; $i -lt $num; $i++) { 67 | $h = @{} 68 | do { 69 | $h.($words[$rnd.Next(0, $totalWords)]) = $null 70 | } until($h.Keys.Count -eq $numWords) 71 | 72 | -join $h.Keys 73 | } -------------------------------------------------------------------------------- /20_password/sonnets/adjs.txt: -------------------------------------------------------------------------------- 1 | able 2 | absent 3 | abundant 4 | acceptable 5 | active 6 | addeth 7 | adjunct 8 | admit 9 | adulterate 10 | adverse 11 | affable 12 | alive 13 | alone 14 | amazeth 15 | amiss 16 | anew 17 | angry 18 | anon 19 | antique 20 | asleep 21 | astonished 22 | aught 23 | aye 24 | babe 25 | backward 26 | bad 27 | balmy 28 | bankrupt 29 | bare 30 | barren 31 | base 32 | beauteous 33 | beautiful 34 | beloved 35 | bent 36 | bereft 37 | bewailed 38 | big 39 | bitter 40 | bl 41 | black 42 | blessed 43 | blind 44 | bloody 45 | blunt 46 | bold 47 | bounteous 48 | bounty 49 | brave 50 | breathe 51 | brief 52 | bright 53 | brightness 54 | broad 55 | budding 56 | buri 57 | busy 58 | captive 59 | careful 60 | celestial 61 | certain 62 | chary 63 | chaste 64 | cheap 65 | chief 66 | civil 67 | clean 68 | clear 69 | cold 70 | common 71 | consecrate 72 | constant 73 | continual 74 | contrary 75 | cool 76 | corrupt 77 | costly 78 | covetous 79 | crooked 80 | cruel 81 | cur'd 82 | curious 83 | dark 84 | dateless 85 | dead 86 | deaf 87 | dear 88 | deceased 89 | deceiv 90 | decrepit 91 | dedicated 92 | deep 93 | delight 94 | delighted 95 | depart 96 | determinate 97 | di 98 | different 99 | dignified 100 | disabled 101 | disdaineth 102 | divine 103 | dost 104 | doting 105 | double 106 | drunk 107 | due 108 | dull 109 | dumb 110 | duteous 111 | dy'd 112 | eager 113 | early 114 | easy 115 | eld 116 | endless 117 | enough 118 | equal 119 | eternal 120 | even 121 | evermore 122 | evident 123 | evil 124 | excellent 125 | extant 126 | extern 127 | external 128 | extreme 129 | fair 130 | false 131 | familiar 132 | fangled 133 | farth 134 | farther 135 | fast 136 | fearful 137 | feather'd 138 | feeble 139 | fell 140 | female 141 | few 142 | fickle 143 | fierce 144 | fiery 145 | fine 146 | firm 147 | first 148 | flat 149 | fleeting 150 | foist 151 | fond 152 | foolish 153 | forbear 154 | forgetful 155 | forlorn 156 | former 157 | forsworn 158 | forward 159 | foul 160 | fragrant 161 | frail 162 | frank 163 | frantic 164 | free 165 | frequent 166 | fresh 167 | front 168 | full 169 | gazed 170 | gazeth 171 | general 172 | gentle 173 | ghastly 174 | glad 175 | glorious 176 | go 177 | golden 178 | good 179 | goodly 180 | gracious 181 | great 182 | grecian 183 | green 184 | grey 185 | gross 186 | guilty 187 | happy 188 | hard 189 | harmful 190 | healthful 191 | hearted 192 | heavenly 193 | heavy 194 | heinous 195 | heretic 196 | hideous 197 | high 198 | holy 199 | honest 200 | hot 201 | huge 202 | humble 203 | humour 204 | hungry 205 | hush 206 | idle 207 | ill 208 | imaginary 209 | immortal 210 | imperfect 211 | impregnable 212 | incapable 213 | inconstant 214 | inferior 215 | injurious 216 | instant 217 | inward 218 | jealous 219 | just 220 | keen 221 | kind 222 | lame 223 | large 224 | lascivious 225 | last 226 | lawful 227 | lean 228 | least 229 | leese 230 | less 231 | lest 232 | light 233 | like 234 | liquid 235 | little 236 | live 237 | lively 238 | lofty 239 | long 240 | loud 241 | lov'd 242 | lovely 243 | loving 244 | low 245 | lusty 246 | mad 247 | maiden 248 | main 249 | makeless 250 | many 251 | married 252 | masked 253 | middle 254 | mighty 255 | minded 256 | mine 257 | modern 258 | more 259 | mortal 260 | most 261 | mournful 262 | mouthed 263 | much 264 | murd'rous 265 | murderous 266 | mute 267 | mutual 268 | naked 269 | ne'er 270 | near 271 | necessary 272 | needy 273 | new 274 | next 275 | niggard 276 | nimble 277 | noted 278 | novel 279 | number'd 280 | o'er 281 | oblivious 282 | obsequious 283 | old 284 | open 285 | other 286 | outcast 287 | outgoing 288 | outlive 289 | outstripp'd 290 | outward 291 | outworn 292 | own 293 | painful 294 | palate 295 | pale 296 | partial 297 | past 298 | perfect 299 | perfumed 300 | perpetual 301 | petty 302 | plain 303 | pleasant 304 | pleased 305 | pleasing 306 | politic 307 | poor 308 | powerful 309 | precious 310 | present 311 | pretty 312 | prime 313 | private 314 | profound 315 | prone 316 | prophetic 317 | proud 318 | public 319 | pure 320 | purple 321 | quick 322 | quiet 323 | ragged 324 | rainy 325 | rare 326 | rebel 327 | red 328 | religious 329 | remote 330 | remov'd 331 | replete 332 | restful 333 | resty 334 | rich 335 | right 336 | ripe 337 | rosy 338 | rotten 339 | rough 340 | rude 341 | sable 342 | sacred 343 | sad 344 | same 345 | scarlet 346 | season'd 347 | second 348 | secret 349 | seemly 350 | seldom 351 | sensual 352 | separable 353 | several 354 | shady 355 | shallow 356 | shalt 357 | sharp 358 | short 359 | sick 360 | sickly 361 | sightless 362 | silent 363 | simple 364 | sinful 365 | single 366 | slight 367 | slow 368 | sluttish 369 | small 370 | sober 371 | soft 372 | sole 373 | solemn 374 | sometime 375 | sorry 376 | soundless 377 | sour 378 | sovereign 379 | spacious 380 | special 381 | speechless 382 | spend'st 383 | sportive 384 | stealth 385 | steel'd 386 | steep 387 | steepy 388 | stern 389 | stormy 390 | stout 391 | straight 392 | strange 393 | strong 394 | subject 395 | substantial 396 | successive 397 | such 398 | suffic'd 399 | suited 400 | sullen 401 | sullied 402 | sunken 403 | sure 404 | suspect 405 | swallow'd 406 | sweet 407 | sweetest 408 | swift 409 | tall 410 | tame 411 | tanned 412 | tatter'd 413 | tender 414 | tenth 415 | testy 416 | thievish 417 | thine 418 | third 419 | threescore 420 | thriftless 421 | thy 422 | tired 423 | triumphant 424 | truant 425 | true 426 | twofold 427 | tyrannous 428 | ugly 429 | uncertain 430 | undivided 431 | unear'd 432 | unfair 433 | unfather'd 434 | unjust 435 | unkind 436 | unkindness 437 | unknown 438 | unlettered 439 | unmoved 440 | unperfect 441 | unprovident 442 | unrespected 443 | unseeing 444 | unseen 445 | unset 446 | unstained 447 | unswept 448 | untainted 449 | untrue 450 | untutor'd 451 | unused 452 | unworthiness 453 | us'd 454 | usest 455 | utmost 456 | vacant 457 | vengeful 458 | very 459 | vexed 460 | vial 461 | view 462 | vile 463 | virgin 464 | virtuous 465 | vouchsafe 466 | vulgar 467 | warm 468 | wary 469 | wasteful 470 | watery 471 | weak 472 | weary 473 | welcome 474 | well 475 | whatsoever 476 | whit 477 | white 478 | wide 479 | wild 480 | wilful 481 | willing 482 | wilt 483 | windy 484 | winged 485 | wiry 486 | wise 487 | wished 488 | woe 489 | woeful 490 | wondrous 491 | worth 492 | worthless 493 | worthy 494 | wrackful 495 | wretched 496 | wrong 497 | yellow 498 | young 499 | youthful 500 | zealous 501 | -------------------------------------------------------------------------------- /20_password/sonnets/verbs.txt: -------------------------------------------------------------------------------- 1 | abhor 2 | abide 3 | abide-- 4 | abuse 5 | accumulate 6 | accuse 7 | achieve 8 | acknowledge 9 | acquaint 10 | acquaintance 11 | add 12 | admire 13 | admit 14 | adore 15 | afford 16 | aggravate 17 | allay'd 18 | allege 19 | allow 20 | alter 21 | alter'd 22 | anchor'd 23 | anger 24 | annex'd 25 | answer 26 | anticipate 27 | appear 28 | apply 29 | approve 30 | arise 31 | array 32 | ask 33 | assail'd 34 | assemble 35 | assur'd 36 | assure 37 | attaint 38 | attend 39 | authorize 40 | base 41 | batter 42 | be 43 | bear 44 | beat 45 | become 46 | befriend 47 | begin 48 | beguile 49 | behold 50 | belie 51 | believe 52 | belong 53 | belove 54 | bemoan 55 | bend 56 | beseem 57 | besiege 58 | besmear'd 59 | bestow 60 | betray 61 | better 62 | better'd 63 | beweep 64 | bid 65 | bide 66 | bind 67 | blame 68 | bless 69 | blot 70 | blunt 71 | blunter 72 | blush 73 | boast 74 | boot 75 | borrow 76 | bow 77 | brag 78 | brave 79 | break 80 | breathe 81 | breed 82 | bring 83 | broil 84 | build 85 | burn 86 | burthen 87 | bury 88 | buy 89 | call 90 | can 91 | canopy 92 | care 93 | carry 94 | carve 95 | cast 96 | catch 97 | cease 98 | censure 99 | change 100 | character 101 | check 102 | chide 103 | choose 104 | chopp'd 105 | churl 106 | clear 107 | cloy 108 | colour 109 | colour'd 110 | come 111 | command 112 | commend 113 | comment 114 | commit 115 | compar'd 116 | compare 117 | compile 118 | complain 119 | compose 120 | compound 121 | condemn 122 | confess 123 | confound 124 | consider 125 | conspire 126 | consum'd 127 | contain 128 | contend 129 | content 130 | contract 131 | control 132 | convert 133 | copy 134 | correct 135 | corrupt 136 | could 137 | count 138 | cover 139 | crave 140 | create 141 | credit 142 | critic 143 | cross 144 | cross'd 145 | crown 146 | cry 147 | cure 148 | curse 149 | cut 150 | cxxxviii 151 | dance 152 | dare 153 | darken 154 | dart 155 | decay 156 | decay'd 157 | deceive 158 | decree 159 | deem 160 | defeat 161 | defy 162 | delay 163 | deliver 164 | deliver'd 165 | delve 166 | denote 167 | deny 168 | depend 169 | derive 170 | desert 171 | deserve 172 | desire 173 | despair 174 | desperate 175 | despise 176 | destroy 177 | detain 178 | determine 179 | devis'd 180 | devise 181 | devour 182 | die 183 | dig 184 | dignify 185 | direct 186 | disdain 187 | diseas'd 188 | disgrac'd 189 | disgrace 190 | dispos'd 191 | dispraise 192 | dissuade 193 | divide 194 | divine 195 | do 196 | dost 197 | dote 198 | doth 199 | doubt 200 | dove 201 | drain'd 202 | draw 203 | dread 204 | dream 205 | dress 206 | dress'd 207 | drink 208 | droop 209 | drop 210 | drown 211 | dry 212 | dull 213 | dwell 214 | eas'd 215 | eat 216 | enclose 217 | end 218 | endear 219 | endure 220 | enfeeble 221 | enforce 222 | engraft 223 | enjoy 224 | enjoy'd 225 | enlighten 226 | enrich 227 | ensconce 228 | entertain 229 | entitle 230 | entomb 231 | envy 232 | ere 233 | err 234 | err'd 235 | evermore 236 | example 237 | exceed 238 | excel 239 | excuse 240 | expiate 241 | expire 242 | express 243 | ey'd 244 | eye 245 | face 246 | fade 247 | faint 248 | fair 249 | fall 250 | fame 251 | famouse 252 | fare 253 | favourite 254 | fear 255 | feast 256 | featur'd 257 | feed 258 | feel 259 | fiend 260 | fight 261 | figur'd 262 | filch 263 | fill 264 | fill'd 265 | find 266 | fire 267 | fit 268 | fix 269 | flatter'd 270 | flee 271 | flow 272 | fly 273 | foil'd 274 | fold 275 | follow 276 | foot 277 | for't 278 | forbid 279 | force 280 | fore 281 | forfeit 282 | forge 283 | forget 284 | forgive 285 | forgo 286 | form 287 | forsake 288 | fortify 289 | fortune 290 | foul 291 | frame 292 | frown 293 | fulfil 294 | gain 295 | gather'd 296 | gaze 297 | gentlest 298 | get 299 | gild 300 | gird 301 | give 302 | glance 303 | glaze 304 | gluttone 305 | go 306 | govern 307 | grace 308 | grant 309 | grave 310 | greet 311 | grieve 312 | grind 313 | groan 314 | ground 315 | grow 316 | guard 317 | guess 318 | guide 319 | gull 320 | hallow'd 321 | halt 322 | hang 323 | happie 324 | hast 325 | haste 326 | hasten 327 | hate 328 | hateth 329 | hath 330 | have 331 | hear 332 | heat 333 | heaven 334 | hide 335 | hie 336 | hoist 337 | hold 338 | honour 339 | hope 340 | hunt 341 | hurt 342 | imitate 343 | immure 344 | impair 345 | impannelle 346 | impart 347 | import 348 | impute 349 | increase 350 | indigest 351 | inflame 352 | inhabit 353 | inherit 354 | insult 355 | intend 356 | invite 357 | invocate 358 | invoke 359 | jack 360 | join 361 | journey 362 | joy 363 | jump 364 | justify 365 | keep 366 | keep'st 367 | kill 368 | kindle 369 | kiss 370 | knit 371 | know 372 | labour 373 | lace 374 | lack 375 | last 376 | laugh'd 377 | lay 378 | lead 379 | leap 380 | leap'd 381 | learn 382 | learn'd 383 | leave 384 | lend 385 | let 386 | level 387 | lie 388 | like 389 | limp 390 | linger 391 | list 392 | live 393 | loathsome 394 | lock 395 | lock'd 396 | look 397 | lose 398 | love 399 | lxiii 400 | lxix 401 | lxxviii 402 | lxxxix 403 | maintain 404 | make 405 | mar 406 | march 407 | mark 408 | marry 409 | mask'd 410 | master 411 | matter 412 | may 413 | mayst 414 | mean 415 | measure 416 | medicine 417 | mend 418 | merit 419 | methink 420 | mightst 421 | mine 422 | misplac'd 423 | mistake 424 | misuse 425 | moan 426 | mock 427 | mortgag'd 428 | mount 429 | mourn 430 | move 431 | mow 432 | must 433 | name 434 | need 435 | neglect 436 | neigh 437 | niggarde 438 | note 439 | nourish'd 440 | nurse 441 | nurseth 442 | o 443 | o'ertake 444 | offend 445 | open 446 | outbrave 447 | outlive 448 | outwear 449 | overturn 450 | owe 451 | own 452 | pace 453 | paint 454 | pardon 455 | part 456 | partake 457 | pass 458 | pattern 459 | pay 460 | pebble 461 | peep 462 | pen 463 | perceive 464 | perish 465 | perjur'd 466 | permit 467 | perspective 468 | persuade 469 | pie 470 | pierc'd 471 | pine 472 | pity 473 | place 474 | play 475 | plead 476 | please 477 | pluck 478 | poet 479 | point 480 | poison 481 | possess 482 | possess'd 483 | prais'd 484 | praise 485 | pray 486 | predict 487 | prefigure 488 | prepare 489 | present 490 | preserve 491 | press 492 | presume 493 | prevail'd 494 | prevent 495 | prick'd 496 | privilage 497 | prize 498 | proceed 499 | proclaim 500 | profan'd 501 | profit 502 | prognosticate 503 | promise 504 | prov'd 505 | prove 506 | provide 507 | provoke 508 | publish 509 | purge 510 | pursue 511 | put 512 | putt'st 513 | qualify 514 | quench 515 | question 516 | ransom 517 | rare 518 | raven 519 | raze 520 | read 521 | receive 522 | recite 523 | reckon 524 | reckon'd 525 | recount 526 | recur'd 527 | reeleth 528 | refigur'd 529 | refine 530 | refusest 531 | register 532 | rehearse 533 | reign 534 | release 535 | remain 536 | remember 537 | remember'd 538 | remove 539 | render 540 | renew 541 | renewest 542 | repair 543 | repay 544 | repose 545 | reprove 546 | require 547 | resemble 548 | reserve 549 | resort 550 | rest 551 | restor'd 552 | restore 553 | return 554 | return'd 555 | rid 556 | ride 557 | rise 558 | rob 559 | ruin 560 | ruinate 561 | run 562 | salve 563 | save 564 | say 565 | scant 566 | scap'd 567 | score 568 | scorn 569 | seal 570 | seal'd 571 | see 572 | see'st 573 | seek 574 | seem 575 | sell 576 | send 577 | serve 578 | set 579 | settle 580 | shake 581 | shall 582 | shalt 583 | shame 584 | shape 585 | share 586 | sharpen 587 | shed 588 | shift 589 | shine 590 | shoot 591 | shorn 592 | should 593 | show 594 | shun 595 | sicken 596 | side 597 | sigh 598 | silence 599 | silver 600 | sin 601 | sing 602 | sink 603 | sit 604 | skill 605 | slander'd 606 | slay 607 | sleep 608 | smell 609 | smile 610 | snow 611 | sound 612 | sparkle 613 | speak 614 | speed 615 | spend 616 | spot 617 | spread 618 | spur 619 | stain 620 | stamp'd 621 | stand 622 | starve 623 | stay 624 | steal 625 | steep 626 | stirr'd 627 | stol'n 628 | stop 629 | store 630 | strain 631 | stretch 632 | strike 633 | strive 634 | strumpete 635 | suborn 636 | subscribe 637 | subsist 638 | succeed 639 | sue 640 | suffer 641 | suffer'd 642 | suggest 643 | suit 644 | sullen 645 | sum 646 | summon 647 | suppose 648 | suppress 649 | surmount 650 | survive 651 | sway 652 | sway'st 653 | swear 654 | swerve 655 | take 656 | tally 657 | task 658 | taste 659 | teach 660 | teachest 661 | tear 662 | teem 663 | tell 664 | tempt 665 | temptation 666 | tend 667 | thank 668 | thee 669 | thence 670 | thine 671 | think 672 | thou 673 | thralle 674 | thrice 675 | thrive 676 | throne 677 | throw 678 | thy 679 | tickle 680 | tie 681 | time 682 | tir'd 683 | tis 684 | toil 685 | toil'd 686 | tombe 687 | top 688 | torment 689 | torture 690 | touch 691 | touch'd 692 | transfix 693 | translate 694 | transport 695 | travel 696 | travell'd 697 | tread 698 | trip 699 | trust 700 | truth 701 | try 702 | tune 703 | turn 704 | twire 705 | unbre 706 | unfold 707 | unlearn 708 | unsway'd 709 | uphold 710 | urge 711 | use 712 | utter 713 | vade 714 | vanish 715 | vary 716 | vaunt 717 | vex 718 | vex'd 719 | view 720 | vouchsafe 721 | vow 722 | vow'd 723 | wail 724 | wait 725 | wake 726 | walk 727 | wane 728 | want 729 | waste 730 | watch 731 | weaken 732 | wear 733 | weep 734 | weigh 735 | west 736 | wet 737 | whereof 738 | will 739 | wilt 740 | win 741 | wink 742 | winter 743 | wish 744 | wit 745 | wither 746 | witness 747 | wonder 748 | woo 749 | work 750 | would 751 | wound 752 | wrest 753 | wrinkle 754 | writ 755 | write 756 | xciii 757 | yield 758 | -------------------------------------------------------------------------------- /20_password/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/20_password/test.ps1 -------------------------------------------------------------------------------- /21_tictactoe/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/21_tictactoe/AllTest.ps1 -------------------------------------------------------------------------------- /21_tictactoe/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/21_tictactoe/README.md -------------------------------------------------------------------------------- /21_tictactoe/solution1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $board = '.' * 9, 18 | [ValidateSet('X', 'O')] 19 | $player, 20 | [ValidateRange(1, 9)] 21 | $cell 22 | ) 23 | 24 | function Update-BoardPosition { 25 | param( 26 | $target, 27 | $position, 28 | $character 29 | ) 30 | 31 | $target = $target.ToCharArray() 32 | $target[$position] = $character 33 | 34 | -join $target 35 | } 36 | 37 | function Format-Board { 38 | param($board) 39 | 40 | $bar = '-------------' 41 | $cellsTmpl = '| {0} | {1} | {2} |' 42 | 43 | $cells = for ($i = 0; $i -lt $board.Length; $i++) { 44 | $currenChar = $board[$i] 45 | if ($currenChar -eq '.') { 46 | $i + 1 47 | } 48 | else { 49 | $currenChar 50 | } 51 | } 52 | 53 | $( 54 | $bar 55 | $cellsTmpl -f $cells[0..2] 56 | $bar 57 | $cellsTmpl -f $cells[3..5] 58 | $bar 59 | $cellsTmpl -f $cells[6..8] 60 | $bar 61 | ) -join "`n" 62 | } 63 | 64 | function Find-Winner { 65 | param($board) 66 | 67 | $winning = $( 68 | , (0, 1, 2) 69 | , (3, 4, 5) 70 | , (6, 7, 8) 71 | , (0, 3, 6) 72 | , (1, 4, 7) 73 | , (2, 5, 8) 74 | , (0, 4, 8) 75 | , (2, 4, 6) 76 | ) 77 | 78 | foreach ($player in 'X', 'O') { 79 | foreach ($item in $winning) { 80 | $i, $j, $k = $item 81 | $combo = $board[$i], $board[$j], $board[$k] 82 | 83 | if (-join $combo -eq $player + $player + $player) { 84 | return $player 85 | } 86 | } 87 | } 88 | } 89 | 90 | if (!($board -cmatch "^[.XO]{9}$")) { 91 | throw ('-board "{0}" must be 9 characters of ., X, O' -f $board) 92 | } 93 | 94 | if ($player -and $cell) { 95 | $board = Update-BoardPosition $board ($cell - 1) $player.ToUpper() 96 | } 97 | 98 | Format-Board $board 99 | 100 | $winner = Find-Winner $board 101 | if ($winner) { 102 | "$winner has won!" 103 | } 104 | else { 105 | "No winner." 106 | } 107 | 108 | -------------------------------------------------------------------------------- /21_tictactoe/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/21_tictactoe/test.ps1 -------------------------------------------------------------------------------- /21_tictactoe/tictactoe.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | Author: Doug Finke 4 | Email: finked@hotmail.com 5 | 6 | Blog: https://dfinke.github.io/ 7 | Twitter: https://twitter.com/dfinke 8 | GitHub: https://github.com/dfinke 9 | YouTube: https://www.youtube.com/dougfinke 10 | 11 | PowerShell Meetup: https://www.meetup.com/NycPowershellMeetup/ 12 | 13 | LinkedIn: https://www.linkedin.com/in/douglasfinke/ 14 | #> 15 | 16 | param( 17 | $board = '.' * 9, 18 | [ValidateSet('X', 'O')] 19 | $player, 20 | [ValidateRange(1, 9)] 21 | $cell 22 | ) 23 | 24 | function Update-BoardPosition { 25 | param( 26 | $target, 27 | $position, 28 | $character 29 | ) 30 | 31 | $target = $target.ToCharArray() 32 | $target[$position] = $character 33 | 34 | -join $target 35 | } 36 | 37 | function Format-Board { 38 | param($board) 39 | 40 | $bar = '-------------' 41 | $cellsTmpl = '| {0} | {1} | {2} |' 42 | 43 | $cells = for ($i = 0; $i -lt $board.Length; $i++) { 44 | $currenChar = $board[$i] 45 | if ($currenChar -eq '.') { 46 | $i + 1 47 | } 48 | else { 49 | $currenChar 50 | } 51 | } 52 | 53 | $( 54 | $bar 55 | $cellsTmpl -f $cells[0..2] 56 | $bar 57 | $cellsTmpl -f $cells[3..5] 58 | $bar 59 | $cellsTmpl -f $cells[6..8] 60 | $bar 61 | ) -join "`n" 62 | } 63 | 64 | function Find-Winner { 65 | param($board) 66 | 67 | $winning = $( 68 | , (0, 1, 2) 69 | , (3, 4, 5) 70 | , (6, 7, 8) 71 | , (0, 3, 6) 72 | , (1, 4, 7) 73 | , (2, 5, 8) 74 | , (0, 4, 8) 75 | , (2, 4, 6) 76 | ) 77 | 78 | foreach ($player in 'X', 'O') { 79 | foreach ($item in $winning) { 80 | $i, $j, $k = $item 81 | $combo = $board[$i], $board[$j], $board[$k] 82 | 83 | if (-join $combo -eq $player + $player + $player) { 84 | return $player 85 | } 86 | } 87 | } 88 | } 89 | 90 | if (!($board -cmatch "^[.XO]{9}$")) { 91 | throw ('-board "{0}" must be 9 characters of ., X, O' -f $board) 92 | } 93 | 94 | if ($player -and $cell) { 95 | $board = Update-BoardPosition $board ($cell - 1) $player.ToUpper() 96 | } 97 | 98 | Format-Board $board 99 | 100 | $winner = Find-Winner $board 101 | if ($winner) { 102 | "$winner has won!" 103 | } 104 | else { 105 | "No winner." 106 | } 107 | 108 | -------------------------------------------------------------------------------- /22_itictactoe/AllTest.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/22_itictactoe/AllTest.ps1 -------------------------------------------------------------------------------- /22_itictactoe/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/22_itictactoe/README.md -------------------------------------------------------------------------------- /22_itictactoe/itictactoe.ps1: -------------------------------------------------------------------------------- 1 | class State { 2 | $board = '.' * 9 3 | $player = 'X' 4 | [bool]$quit 5 | [bool]$draw 6 | $error 7 | $winner 8 | } 9 | 10 | function Test-IsNumeric ($Value) { 11 | $Value -match "^[\d\.]+$" 12 | } 13 | 14 | function Update-BoardPosition { 15 | param( 16 | $board, 17 | $position, 18 | $player 19 | ) 20 | 21 | $board = $board.ToCharArray() 22 | $board[$position] = $player 23 | 24 | -join $board 25 | } 26 | 27 | function Format-Board { 28 | param($board) 29 | 30 | $bar = '-------------' 31 | $cellsTmpl = '| {0} | {1} | {2} |' 32 | 33 | $cells = for ($i = 0; $i -lt $board.Length; $i++) { 34 | $currenChar = $board[$i] 35 | if ($currenChar -eq '.') { 36 | $i + 1 37 | } 38 | else { 39 | $currenChar 40 | } 41 | } 42 | 43 | $( 44 | $bar 45 | $cellsTmpl -f $cells[0..2] 46 | $bar 47 | $cellsTmpl -f $cells[3..5] 48 | $bar 49 | $cellsTmpl -f $cells[6..8] 50 | $bar 51 | ) -join "`n" 52 | } 53 | 54 | function Find-Winner { 55 | param($board) 56 | 57 | $winning = $( 58 | , (0, 1, 2) 59 | , (3, 4, 5) 60 | , (6, 7, 8) 61 | , (0, 3, 6) 62 | , (1, 4, 7) 63 | , (2, 5, 8) 64 | , (0, 4, 8) 65 | , (2, 4, 6) 66 | ) 67 | 68 | foreach ($player in 'X', 'O') { 69 | foreach ($item in $winning) { 70 | $i, $j, $k = $item 71 | $combo = $board[$i], $board[$j], $board[$k] 72 | 73 | if (-join $combo -eq $player + $player + $player) { 74 | return $player 75 | } 76 | } 77 | } 78 | } 79 | 80 | function Get-Move { 81 | param($state) 82 | 83 | $player = $state.player 84 | $cell = Read-Host "Player $($state.player), what is your move? [q to quit]" 85 | 86 | if ($cell -eq 'q') { 87 | $state.quit = $true 88 | return $state 89 | } 90 | 91 | if (!(Test-IsNumeric $cell) -or !($cell -in 1..9)) { 92 | $state.error = "Invalid cell `"$cell`", please use 1-9" 93 | return $state 94 | } 95 | 96 | $cell_num = [int] $cell 97 | 98 | if ($state.board[$cell_num - 1] -match '[XO]') { 99 | $state.error = "Cell `"$cell`" already taken" 100 | return $state 101 | } 102 | 103 | $board = $state.board 104 | 105 | $board = Update-BoardPosition $board ($cell_num - 1) $player 106 | 107 | $state.board = $board 108 | $state.player = if ($player -eq 'X') { 'O' } else { 'X' } 109 | $state.winner = Find-Winner $board 110 | $state.draw = $board.IndexOf('.') -eq -1 111 | $state.error = $null 112 | 113 | return $state 114 | } 115 | 116 | $state = [State]::new() 117 | 118 | while ($true) { 119 | Format-Board $state.board 120 | 121 | if ($state.error) { 122 | $state.error 123 | } 124 | elseif ($state.winner) { 125 | "$($state.winner) has won!" 126 | break 127 | } 128 | 129 | $state = Get-Move $state 130 | 131 | if ($state.quit) { 132 | 'You lose!' 133 | break 134 | } 135 | elseif ($state.draw) { 136 | "All right, we'll call it a draw." 137 | break 138 | } 139 | } -------------------------------------------------------------------------------- /22_itictactoe/test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfinke/Tiny-PowerShell-Projects/ecc1c625d9e58708c911f08b9fc14eee885aae78/22_itictactoe/test.ps1 -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jupyter/base-notebook:latest 2 | 3 | # Install .NET CLI dependencies 4 | 5 | ARG NB_USER=jovyan 6 | ARG NB_UID=1000 7 | ENV USER ${NB_USER} 8 | ENV NB_UID ${NB_UID} 9 | ENV HOME /home/${NB_USER} 10 | 11 | WORKDIR ${HOME} 12 | 13 | USER root 14 | RUN apt-get update 15 | RUN apt-get install -y curl 16 | 17 | ENV \ 18 | # Enable detection of running in a container 19 | DOTNET_RUNNING_IN_CONTAINER=true \ 20 | # Enable correct mode for dotnet watch (only mode supported in a container) 21 | DOTNET_USE_POLLING_FILE_WATCHER=true \ 22 | # Skip extraction of XML docs - generally not useful within an image/container - helps performance 23 | NUGET_XMLDOC_MODE=skip \ 24 | # Opt out of telemetry until after we install jupyter when building the image, this prevents caching of machine id 25 | DOTNET_TRY_CLI_TELEMETRY_OPTOUT=true 26 | 27 | # Install .NET CLI dependencies 28 | RUN apt-get update \ 29 | && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ 30 | libc6 \ 31 | libgcc1 \ 32 | libgssapi-krb5-2 \ 33 | libicu66 \ 34 | libssl1.1 \ 35 | libstdc++6 \ 36 | zlib1g \ 37 | && rm -rf /var/lib/apt/lists/* 38 | 39 | # Install .NET Core SDK 40 | RUN dotnet_sdk_version=3.1.301 \ 41 | && curl -SL --output dotnet.tar.gz https://dotnetcli.azureedge.net/dotnet/Sdk/$dotnet_sdk_version/dotnet-sdk-$dotnet_sdk_version-linux-x64.tar.gz \ 42 | && dotnet_sha512='dd39931df438b8c1561f9a3bdb50f72372e29e5706d3fb4c490692f04a3d55f5acc0b46b8049bc7ea34dedba63c71b4c64c57032740cbea81eef1dce41929b4e' \ 43 | && echo "$dotnet_sha512 dotnet.tar.gz" | sha512sum -c - \ 44 | && mkdir -p /usr/share/dotnet \ 45 | && tar -ozxf dotnet.tar.gz -C /usr/share/dotnet \ 46 | && rm dotnet.tar.gz \ 47 | && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \ 48 | # Trigger first run experience by running arbitrary cmd 49 | && dotnet help 50 | 51 | # Copy notebooks 52 | COPY ./ ${HOME}/Notebooks/ 53 | 54 | # Copy package sources 55 | COPY ./NuGet.config ${HOME}/nuget.config 56 | 57 | RUN chown -R ${NB_UID} ${HOME} 58 | USER ${USER} 59 | 60 | #Install nteract 61 | RUN pip install nteract_on_jupyter 62 | 63 | # Install lastest build from main branch of Microsoft.DotNet.Interactive from myget 64 | RUN dotnet tool install -g Microsoft.dotnet-interactive --version 1.0.140401 --add-source "https://dotnet.myget.org/F/dotnet-try/api/v3/index.json" 65 | 66 | ENV PATH="${PATH}:${HOME}/.dotnet/tools" 67 | RUN echo "$PATH" 68 | 69 | # Install kernel specs 70 | RUN dotnet interactive jupyter install 71 | 72 | # Enable telemetry once we install jupyter for the image 73 | ENV DOTNET_TRY_CLI_TELEMETRY_OPTOUT=false 74 | 75 | # Set root to Notebooks 76 | WORKDIR ${HOME}/Notebooks/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Doug Finke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | # Tiny PowerShell Projects 13 | 14 | This is the code repository for _Tiny **PowerShell** Projects_. 15 | 16 | I ported it from the Manning Publications book, _Tiny Python Projects_, by Ken Youens-Clark: 17 | 18 | - The Python repo is here: https://github.com/kyclark/tiny_python_projects 19 | - The Python book is here: https://www.manning.com/books/tiny-python-projects?a_aid=youens&a_bid=b6485d52 20 | 21 | One of the many cool aspects of this not only the approach to learning `PowerShell` this way, additionally, you can head over to the `Python` repo and see how it is done in that language. Could be you are here because you're a Pythonista, and want to see how PoShers do it. 22 | 23 | Either way, it's the same puzzles implemented in both languages, and you can use the tests provided, to do Test Driven Development and prove these and your solutions work, as you make changes. 24 | 25 | ## The Video 26 | Scripting Success A Deep Dive into Tiny PowerShell Projects. 27 | 28 | 29 | 30 | 31 | ## The approach 32 | 33 | There is a directory for each chapter of the book. 34 | There is a README to describe each exercise. 35 | Each directory contains a `test.ps1` program you can use with `Invoke-Pester` to check that you have written the program correctly. 36 | 37 | In addition, each directory has two `PowerShell` scripts, one called `AllTest.ps1`, and the other `solution1.ps1`. 38 | 39 | ## AllTest 40 | 41 | `AllTest.ps1` does something very _beneficial_. It looks in that chapters directory for all files that match the wildcard `solution*.ps1`, and one by one copies it to a `ps1` that is expected in the `test.ps1`, and the last step, it calls `Invoke-Pester`. 42 | 43 | This allows you to keep the original solution supplied, and you can then create as many solutions as you'd like to test different ways to solve the puzzle. This lets you experiment with different ways to use a regex, arrays, hash tables or other approaches, in order to figure out better ways to handle this. The different solutions can sit side by side with the others and the `test.ps1` can be automatically run against all. 44 | 45 | ## Testing is Integral 46 | The testing step is integral to writing and solving these challenges. 47 | 48 | Using a "test-driven development" mentality, where you write tests _before_ you write code, is very much recommended. 49 | 50 | The tests should define what it means for a program to be correct, and then you write programs to satisfy the tests. 51 | 52 | All the tests have been written for you, and you should write your own functions and tests. 53 | Practice is key. 54 | 55 | You should run the test suite after every change to your program to ensure you are making progress! 56 | 57 | ## Chapters 58 | 59 | * [Chapter 1: How to write and test a PowerShell program](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/01_hello) How to create a PowerShell program that prints a string and takes a parameter. [[source code]](./01_hello/hello.ps1) 60 | 61 | * [Chapter 2: Crow's Nest](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/02_crowsnest) How to write a PowerShell program that accepts a single, positional argument and creates a newly formatted output string. [[source code]](./02_crowsnest/crowsnest.ps1) 62 | 63 | * [Chapter 3: Picnic](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/03_picnic) Writing a PowerShell program that accepts multiple string arguments and formats the results depending on the number of items. [[source code]](./03_picnic/picnic.ps1) 64 | 65 | * [Chapter 4: Jump The Five](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/04_jump_the_five) Writing a PowerShell program to encode the numerals in a given text using an algorithm called "Jump The Five." Use of a dictionary as a lookup table, characters not in the dictionary remain unchanged. Introduction to encoding/decoding text, basic idea of encryption. [[source code]](./04_jump_the_five/jump.ps1) 66 | 67 | * [Chapter 5: Howler](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/05_howler) Writing a PowerShell program that can process input text either from the command line or from a file.The output prints either to STDOUT or to a file. Learning about how to read/write the contents of a file. [[source code]](./05_howler/howler.ps1) 68 | 69 | * [Chapter 6: Word Count](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/06_wc) Writing a PowerShell program to emulate a word count program. Validates and processes multiple file inputs as well as STDIN and creates output of the counts of lines, words, and characters for each file. [[source code]](./06_wc/wc.ps1) 70 | 71 | * [Chapter 7: Gashlycrumb](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/07_gashlycrumb) Writing a PowerShell program that processes an input file to build a lookup table (dictionary) that is used with multiple positional arguments to translate to the values from the file. [[source code]](./07_gashlycrumb/gashlycrumb.ps1) 72 | 73 | * [Chapter 8: Apples and Bananas](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/08_apples_and_bananas) Writing a PowerShell program to find and replace elements in a string. [[source code]](./08_apples_and_bananas/apples.ps1) 74 | 75 | * [Chapter 9: Abuse](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/09_abuse) Writing a PowerShell program to generate Shakespearean insults by randomly combining some number of adjectives with a randomly chosen noun. Learning about randomness, seeds, and testing. [[source code]](./09_abuse/abuse.ps1) 76 | 77 | * [Chapter 10: Telephone](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/10_telephone) Using probabilistic and deterministic approaches to randomly mutate a string. [[source code]](./10_telephone/telephone.ps1) 78 | 79 | * [Chapter 11: Bottles of Beer](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/11_bottles_of_beer 80 | ) Writing a PowerShell program to produce the verse to the "99 Bottles of Beer" song from a given starting point. Learning to count down, format strings, algorithm design. A focus on writing a function and unit test, exploring ways to incorporate our function to generate the verses from for loops. [[source code]](./11_bottles_of_beer/bottles.ps1) 81 | 82 | * [Chapter 12: Ransom](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/12_ransom) Writing a PowerShell program that will randomly capitalize letters in a given piece of text for the nefarious purpose of creating a ransom note. [[source code]](./12_ransom/ransom.ps1) 83 | 84 | * [Chapter 13: Twelve Days of Christmas](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/13_twelve_days) Writing a PowerShell program to create the verses for "The Twelve Days of Christmas" from a given day. Learning how to write a function and the test for it, then using the function in a list to generate the output. [[source code]](./13_twelve_days/twelve_days.ps1) 85 | 86 | * [Chapter 14: The Rhymer](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/14_rhymer) Writing a PowerShell program that can split off any initial consonants from a word and append a list of prefixes to create new rhyming "words." Exploration of regular expressions to handle words with no initial consonants, with one or more leading consonants, and nothing but consonants. [[source code]](./14_rhymer/rhymer.ps1) 87 | 88 | * [Chapter 15: The Kentucky Friar](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/15_kentucky_friar) In this chapter we delve further into regular expressions, first learning how to split a string using a regex so we can separate things that look like "words" from non-words like punctuation and whitespace. Then we try to identify the word "you" (case-insensitive) to turn into "y'all" and any 2-syllable words ending in "-ing" so we can replace the final "g" with an apostrophe so that "cooking" becomes "cookin'" but "swing" would remain "swing." We then apply this to an entire body of text to Kentucky fry the words with amusing results. [[source code]](./15_kentucky_friar/friar.ps1) 89 | 90 | * [Chapter 16: The Scrambler](https://github.com/dfinke/Tiny-PowerShell-Projects/tree/master/16_scrambler) Writing a PowerShell program to find each "word" in a body of text and then scramble the letters such that the first and last letters remain in place, then reconstructing the text for output. Using regular expressions to split text, using `Sort-Object { Get-Random }`. [[source code]](./16_scrambler/scrambler.ps1) 91 | 92 | 93 | 94 | 149 | -------------------------------------------------------------------------------- /RunAllTests.ps1: -------------------------------------------------------------------------------- 1 | foreach ($target in Get-ChildItem -Directory | Where-Object { $_.name -match '^\d{2}' }) { 2 | Push-Location 3 | Set-Location $target 4 | ./AllTest.ps1 5 | Pop-Location 6 | } -------------------------------------------------------------------------------- /UtilityModules/UtilityModules.psm1: -------------------------------------------------------------------------------- 1 | function Get-RandomSample { 2 | <# 3 | .Synopsis 4 | Random sampling and randomly pick more than one element from the list without repeating elements 5 | .Description 6 | The $list can be any sequence such as list, set from which you want to select a k length number 7 | The k is the number of random items you want to select from the sequence 8 | Get-RandomSample doesn’t repeat the items in the result list 9 | .Example 10 | Get-RandomSample 20, 40, 80, 100, 120 3 11 | 20 12 | 100 13 | 120 14 | 15 | .Example 16 | Get-RandomSample (1..10) 3 17 | 10 18 | 8 19 | 7 20 | 21 | .Example 22 | Get-RandomSample a, b, c 3 23 | c 24 | a 25 | b 26 | 27 | #> 28 | param( 29 | $list, 30 | $k 31 | ) 32 | 33 | if ($k -gt $list.Count) { throw "k must be less than the size of the list" } 34 | 35 | # if($k -eq 0) {return $list} 36 | if($k -eq 0) {return $null} 37 | 38 | $h = @{} 39 | 40 | do { 41 | $h.($list | Get-Random) = $null 42 | } until($h.Keys.Count -eq $k) 43 | 44 | $h.Keys 45 | } 46 | 47 | function Get-AsciiLowercase { 48 | <# 49 | .Synopsis 50 | Gets lowercase letters 'abcdefghijklmnopqrstuvwxyz' 51 | #> 52 | -join ([int][char]'a'..[int][char]'z' | ForEach-Object { [char]$_ }) 53 | } 54 | 55 | function Get-AsciiUppercase { 56 | <# 57 | .Synopsis 58 | Gets lowercase letters 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 59 | #> 60 | -join ([int][char]'A'..[int][char]'Z' | ForEach-Object { [char]$_ }) 61 | } 62 | 63 | function Get-AsciiLetters { 64 | <# 65 | .Synopsis 66 | Concatenation of Get-AsciiLowercase and Get-AsciiUppercase 67 | #> 68 | (Get-AsciiLowercase) + (Get-AsciiUppercase) 69 | } 70 | 71 | function Get-AsciiPunctuation { 72 | <# 73 | .Synopsis 74 | Get all Ascii punctuation 75 | #> 76 | $ascii = 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 58, 59, 60, 61, 62, 63, 91, 92, 93, 94, 95, 96, 123, 124, 125, 126 77 | 78 | $(foreach ($item in $ascii) { 79 | [char]$item 80 | }) -join '' 81 | } 82 | 83 | function Get-Digits { 84 | '0123456789' 85 | } 86 | 87 | function Invoke-MakeTranslation { 88 | <# 89 | .Synopsis 90 | Returns a translation table that maps each character in the intabstring into the character at the same position in the outtabstring 91 | #> 92 | param( 93 | [string]$inTabString, 94 | [string]$outTabString 95 | ) 96 | 97 | if ($inTabString.Length -ne $outTabString.Length) { 98 | throw "both need to be the same length" 99 | } 100 | 101 | $count = $inTabString.Length 102 | $h = @{} 103 | 104 | for ($i = 0; $i -lt $count; $i++) { 105 | $key = $inTabString[$i] 106 | $h.$key = $outTabString[$i] 107 | } 108 | 109 | $h 110 | } 111 | 112 | function Invoke-Translate { 113 | <# 114 | .Synopsis 115 | Returns a string that is modified string of givens string according to given translation mappings 116 | #> 117 | param( 118 | $text, 119 | [hashtable]$translateMap 120 | ) 121 | 122 | -join $( 123 | for ($i = 0; $i -lt $text.Length; $i++) { 124 | $currentChar = $text[$i] 125 | $newChar = $translateMap.$currentChar 126 | if ($newChar) { 127 | $newChar 128 | } 129 | else { 130 | $currentChar 131 | } 132 | } 133 | ) 134 | } -------------------------------------------------------------------------------- /inputFiles/fox.txt: -------------------------------------------------------------------------------- 1 | The quick brown fox jumps over the lazy dog. -------------------------------------------------------------------------------- /inputFiles/gettysburg.txt: -------------------------------------------------------------------------------- 1 | Four score and seven years ago our fathers brought forth on this 2 | continent, a new nation, conceived in Liberty, and dedicated to the 3 | proposition that all men are created equal. 4 | 5 | Now we are engaged in a great civil war, testing whether that nation, 6 | or any nation so conceived and so dedicated, can long endure. We are 7 | met on a great battle-field of that war. We have come to dedicate a 8 | portion of that field, as a final resting place for those who here 9 | gave their lives that that nation might live. It is altogether fitting 10 | and proper that we should do this. 11 | 12 | But, in a larger sense, we can not dedicate -- we can not consecrate 13 | -- we can not hallow -- this ground. The brave men, living and dead, 14 | who struggled here, have consecrated it, far above our poor power to 15 | add or detract. The world will little note, nor long remember what we 16 | say here, but it can never forget what they did here. It is for us the 17 | living, rather, to be dedicated here to the unfinished work which they 18 | who fought here have thus far so nobly advanced. It is rather for us 19 | to be here dedicated to the great task remaining before us -- that 20 | from these honored dead we take increased devotion to that cause for 21 | which they gave the last full measure of devotion -- that we here 22 | highly resolve that these dead shall not have died in vain -- that 23 | this nation, under God, shall have a new birth of freedom -- and that 24 | government of the people, by the people, for the people, shall not 25 | perish from the earth. -------------------------------------------------------------------------------- /inputFiles/issa.txt: -------------------------------------------------------------------------------- 1 | Selected Haiku by Issa 2 | 3 | Don't worry, spiders, 4 | I keep house 5 | casually. 6 | 7 | New Year's Day- 8 | everything is in blossom! 9 | I feel about average. 10 | 11 | The snow is melting 12 | and the village is flooded 13 | with children. 14 | 15 | Goes out, 16 | comes back- 17 | the love life of a cat. 18 | 19 | Mosquito at my ear- 20 | does he think 21 | I'm deaf? 22 | 23 | Under the evening moon 24 | the snail 25 | is stripped to the waist. 26 | 27 | Even with insects- 28 | some can sing, 29 | some can't. 30 | 31 | All the time I pray to Buddha 32 | I keep on 33 | killing mosquitoes. 34 | 35 | Napped half the day; 36 | no one 37 | punished me! -------------------------------------------------------------------------------- /inputFiles/nobody.txt: -------------------------------------------------------------------------------- 1 | I'm Nobody! Who are you? 2 | Are you -- Nobody -- too? 3 | Then there's a pair of us! 4 | Don't tell! they'd advertise -- you know! 5 | 6 | How dreary -- to be -- Somebody! 7 | How public -- like a Frog -- 8 | To tell one's name -- the livelong June -- 9 | To an admiring Bog! -------------------------------------------------------------------------------- /inputFiles/now.txt: -------------------------------------------------------------------------------- 1 | Now is the time for all good men to come to the aid of the party. -------------------------------------------------------------------------------- /inputFiles/out.txt: -------------------------------------------------------------------------------- 1 | this is some text 2 | this is some more text -------------------------------------------------------------------------------- /inputFiles/preamble.txt: -------------------------------------------------------------------------------- 1 | When, in the course of human events, it becomes necessary for one people to 2 | dissolve the political bands which have connected them with another, and to 3 | assume among the powers of the earth, the separate and equal station to 4 | which the laws of nature and of nature's God entitle them, a decent respect 5 | to the opinions of mankind requires that they should declare the causes 6 | which impel them to the separation. -------------------------------------------------------------------------------- /inputFiles/sonnet-29.txt: -------------------------------------------------------------------------------- 1 | Sonnet 29 2 | William Shakespeare 3 | 4 | When, in disgrace with fortune and men’s eyes, 5 | I all alone beweep my outcast state, 6 | And trouble deaf heaven with my bootless cries, 7 | And look upon myself and curse my fate, 8 | Wishing me like to one more rich in hope, 9 | Featured like him, like him with friends possessed, 10 | Desiring this man’s art and that man’s scope, 11 | With what I most enjoy contented least; 12 | Yet in these thoughts myself almost despising, 13 | Haply I think on thee, and then my state, 14 | (Like to the lark at break of day arising 15 | From sullen earth) sings hymns at heaven’s gate; 16 | For thy sweet love remembered such wealth brings 17 | That then I scorn to change my state with kings. -------------------------------------------------------------------------------- /inputFiles/spiders.txt: -------------------------------------------------------------------------------- 1 | Don't worry, spiders, 2 | I keep house 3 | casually. -------------------------------------------------------------------------------- /inputFiles/the-bustle.txt: -------------------------------------------------------------------------------- 1 | The bustle in a house 2 | The morning after death 3 | Is solemnest of industries 4 | Enacted upon earth,-- 5 | 6 | The sweeping up the heart, 7 | And putting love away 8 | We shall not want to use again 9 | Until eternity. -------------------------------------------------------------------------------- /inputFiles/usdeclar.txt: -------------------------------------------------------------------------------- 1 | Declaration of Independence 2 | 3 | [Adopted in Congress 4 July 1776] 4 | 5 | 6 | 7 | The Unanimous Declaration of the Thirteen United States of America 8 | 9 | When, in the course of human events, it becomes necessary for one people to 10 | dissolve the political bands which have connected them with another, and to 11 | assume among the powers of the earth, the separate and equal station to 12 | which the laws of nature and of nature's God entitle them, a decent respect 13 | to the opinions of mankind requires that they should declare the causes 14 | which impel them to the separation. 15 | 16 | We hold these truths to be self-evident, that all men are created equal, 17 | that they are endowed by their Creator with certain unalienable rights, that 18 | among these are life, liberty and the pursuit of happiness. That to secure 19 | these rights, governments are instituted among men, deriving their just 20 | powers from the consent of the governed. That whenever any form of 21 | government becomes destructive of these ends, it is the right of the people 22 | to alter or to abolish it, and to institute new government, laying its 23 | foundation on such principles and organizing its powers in such form, as to 24 | them shall seem most likely to effect their safety and happiness. Prudence, 25 | indeed, will dictate that governments long established should not be changed 26 | for light and transient causes; and accordingly all experience hath shown 27 | that mankind are more disposed to suffer, while evils are sufferable, than 28 | to right themselves by abolishing the forms to which they are accustomed. 29 | But when a long train of abuses and usurpations, pursuing invariably the 30 | same object evinces a design to reduce them under absolute despotism, it is 31 | their right, it is their duty, to throw off such government, and to provide 32 | new guards for their future security. -- Such has been the patient 33 | sufferance of these colonies; and such is now the necessity which constrains 34 | them to alter their former systems of government. The history of the present 35 | King of Great Britain is a history of repeated injuries and usurpations, all 36 | having in direct object the establishment of an absolute tyranny over these 37 | states. To prove this, let facts be submitted to a candid world. 38 | 39 | He has refused his assent to laws, the most wholesome and 40 | necessary for the public good. 41 | 42 | He has forbidden his governors to pass laws of immediate 43 | and pressing importance, unless suspended in their 44 | operation till his assent should be obtained; and when so 45 | suspended, he has utterly neglected to attend to them. 46 | 47 | He has refused to pass other laws for the accommodation 48 | of large districts of people, unless those people would 49 | relinquish the right of representation in the legislature, a 50 | right inestimable to them and formidable to tyrants only. 51 | 52 | He has called together legislative bodies at places unusual, 53 | uncomfortable, and distant from the depository of their 54 | public records, for the sole purpose of fatiguing them into 55 | compliance with his measures. 56 | 57 | He has dissolved representative houses repeatedly, for 58 | opposing with manly firmness his invasions on the rights of 59 | the people. 60 | 61 | He has refused for a long time, after such dissolutions, to 62 | cause others to be elected; whereby the legislative powers, 63 | incapable of annihilation, have returned to the people at 64 | large for their exercise; the state remaining in the meantime 65 | exposed to all the dangers of invasion from without, and 66 | convulsions within. 67 | 68 | He has endeavored to prevent the population of these 69 | states; for that purpose obstructing the laws for 70 | naturalization of foreigners; refusing to pass others to 71 | encourage their migration hither, and raising the conditions 72 | of new appropriations of lands. 73 | 74 | He has obstructed the administration of justice, by refusing 75 | his assent to laws for establishing judiciary powers. 76 | 77 | He has made judges dependent on his will alone, for the 78 | tenure of their offices, and the amount and payment of their 79 | salaries. 80 | 81 | He has erected a multitude of new offices, and sent hither 82 | swarms of officers to harass our people, and eat out their 83 | substance. 84 | 85 | He has kept among us, in times of peace, standing armies 86 | without the consent of our legislature. 87 | 88 | He has affected to render the military independent of and 89 | superior to civil power. 90 | 91 | He has combined with others to subject us to a jurisdiction 92 | foreign to our constitution, and unacknowledged by our 93 | laws; giving his assent to their acts of pretended legislation: 94 | 95 | For quartering large bodies of armed troops among us: 96 | 97 | For protecting them, by mock trial, from punishment for 98 | any murders which they should commit on the inhabitants 99 | of these states: 100 | 101 | For cutting off our trade with all parts of the world: 102 | 103 | For imposing taxes on us without our consent: 104 | 105 | For depriving us in many cases, of the benefits of trial by 106 | jury: 107 | 108 | For transporting us beyond seas to be tried for pretended 109 | offenses: 110 | 111 | For abolishing the free system of English laws in a 112 | neighboring province, establishing therein an arbitrary 113 | government, and enlarging its boundaries so as to render it 114 | at once an example and fit instrument for introducing the 115 | same absolute rule in these colonies: 116 | 117 | For taking away our charters, abolishing our most valuable 118 | laws, and altering fundamentally the forms of our 119 | governments: 120 | 121 | For suspending our own legislatures, and declaring 122 | themselves invested with power to legislate for us in all 123 | cases whatsoever. 124 | 125 | He has abdicated government here, by declaring us out of 126 | his protection and waging war against us. 127 | 128 | He has plundered our seas, ravaged our coasts, burned 129 | our towns, and destroyed the lives of our people. 130 | 131 | He is at this time transporting large armies of foreign 132 | mercenaries to complete the works of death, desolation 133 | and tyranny, already begun with circumstances of cruelty 134 | and perfidy scarcely paralleled in the most barbarous ages, 135 | and totally unworthy of the head of a civilized nation. 136 | 137 | He has constrained our fellow citizens taken captive on the 138 | high seas to bear arms against their country, to become the 139 | executioners of their friends and brethren, or to fall 140 | themselves by their hands. 141 | 142 | He has excited domestic insurrections amongst us, and has 143 | endeavored to bring on the inhabitants of our frontiers, the 144 | merciless Indian savages, whose known rule of warfare, is 145 | undistinguished destruction of all ages, sexes and 146 | conditions. 147 | 148 | In every stage of these oppressions we have petitioned for redress in the 149 | most humble terms: our repeated petitions have been answered only by 150 | repeated injury. A prince, whose character is thus marked by every act which 151 | may define a tyrant, is unfit to be the ruler of a free people. 152 | 153 | Nor have we been wanting in attention to our British brethren. We have 154 | warned them from time to time of attempts by their legislature to extend an 155 | unwarrantable jurisdiction over us. We have reminded them of the 156 | circumstances of our emigration and settlement here. We have appealed to 157 | their native justice and magnanimity, and we have conjured them by the ties 158 | of our common kindred to disavow these usurpations, which, would inevitably 159 | interrupt our connections and correspondence. They too have been deaf to the 160 | voice of justice and of consanguinity. We must, therefore, acquiesce 161 | in the necessity, which denounces our separation, and hold them, as we hold 162 | the rest of mankind, enemies in war, in peace friends. 163 | 164 | We, therefore, the representatives of the United States of America, in 165 | General Congress, assembled, appealing to the Supreme Judge of the world for 166 | the rectitude of our intentions, do, in the name, and by the authority of 167 | the good people of these colonies, solemnly publish and declare, that these 168 | united colonies are, and of right ought to be free and independent states; 169 | that they are absolved from all allegiance to the British Crown, and that 170 | all political connection between them and the state of Great Britain, is and 171 | ought to be totally dissolved; and that as free and independent states, they 172 | have full power to levey war, conclude peace, contract alliances, establish 173 | commerce, and to do all other acts and things which independent states may 174 | of right do. And for the support of this declaration, with a firm reliance 175 | on the protection of Divine Providence, we mutually pledge to each other our 176 | lives, our fortunes and our sacred honor. --------------------------------------------------------------------------------