├── .gitignore ├── screenshot.png ├── source ├── icon.png ├── percent.png ├── LICENSE.txt ├── info.plist └── percent.py ├── PercentChange1-6.alfredworkflow ├── AUTHORS.md ├── LICENSE.txt └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.pyc 3 | __pycache__ 4 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradmontgomery/alfred-percent-change/HEAD/screenshot.png -------------------------------------------------------------------------------- /source/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradmontgomery/alfred-percent-change/HEAD/source/icon.png -------------------------------------------------------------------------------- /source/percent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradmontgomery/alfred-percent-change/HEAD/source/percent.png -------------------------------------------------------------------------------- /PercentChange1-6.alfredworkflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradmontgomery/alfred-percent-change/HEAD/PercentChange1-6.alfredworkflow -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Authors & Contributors 2 | 3 | - [Brad Montgomery](mailto:brad@bradmontgomery.net) 4 | - [Adam Wagner](https://github.com/AdamWagner) 5 | - [Giovanni Coppola](https://github.com/giovannicoppola) 6 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018, Brad Montgomery 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /source/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018, Brad Montgomery 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Percent Change 2 | -------------- 3 | 4 | This is an Alfred Workflow to help you do percentage calculations. You can see 5 | some background info on the original [forum post](http://www.alfredforum.com/topic/4731-percent-change/). 6 | 7 | March 2022 updated to Python 3 8 | -------------- 9 | 10 | 11 | Downloads
13 |
14 | 15 | ---------------- 16 | 17 | 18 | The supported calculations include: 19 | 20 | 1. *Percent Change* (increase/decrease): `% 3 6` -> 100% 21 | 2. *Percentage Of*: 3 is what percent of 100: `% 3 of 100` -> 3% 22 | 3. *Percent Of*: 5 percent of 100 is 5: `% 5 percent of 100` -> 5, or `% 5% of 100` -> 5 23 | 4. *Percent Decrease*: What is 2 percent from 100: `% 100 - 2%` 24 | 5. *Percent Increase*: What is 100 + 2%: `% 100 + 2%` 25 | 6. *Original number before Percent Decrease*: What number is 100 2 percent less than?:`% 100 is 2% lt` 26 | 7. *Original number before Percent Increase*: What number is 100 2 percent more than?:`% 100 is 2% gt` 27 | 28 | ## Build: 29 | 30 | - Building uses the [workflow-build.py script](https://gist.github.com/AdamWagner/38228953422e830c4484e62ff116466a) 31 | bundled in this repo. 32 | - To build, run: `python workflow-build.py -f -d . -o .` 33 | 34 | 35 | ## License 36 | 37 | This Workflow is available under the terms of the MIT License. See the full 38 | [LICENSE](LICENSE.txt) for more details. 39 | 40 | 41 | ## Contributing 42 | 43 | Contributions to this project are welcome. To contribute, feel free to fork 44 | this repo, add your changes/features/improvements, then open a pull request. 45 | Don't for get to add your name to the [AUTHORS file](AUTHORS.md). 46 | -------------------------------------------------------------------------------- /source/info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | giovanni.percent_change 7 | category 8 | Tools 9 | connections 10 | 11 | createdby 12 | giovanni from Brad Montgomery 13 | description 14 | Easily do percentage calculations. 15 | disabled 16 | 17 | name 18 | Percent Change 19 | objects 20 | 21 | 22 | config 23 | 24 | alfredfiltersresults 25 | 26 | alfredfiltersresultsmatchmode 27 | 0 28 | argumenttreatemptyqueryasnil 29 | 30 | argumenttrimmode 31 | 0 32 | argumenttype 33 | 0 34 | escaping 35 | 102 36 | keyword 37 | % 38 | queuedelaycustom 39 | 1 40 | queuedelayimmediatelyinitially 41 | 42 | queuedelaymode 43 | 0 44 | queuemode 45 | 1 46 | runningsubtext 47 | calculating 48 | script 49 | python3 percent.py "$1" 50 | scriptargtype 51 | 1 52 | scriptfile 53 | 54 | subtext 55 | Use "% help" to see examples. 56 | title 57 | Percent Calculations 58 | type 59 | 5 60 | withspace 61 | 62 | 63 | type 64 | alfred.workflow.input.scriptfilter 65 | uid 66 | ABB6BA81-8665-40FE-A867-448DF94386CA 67 | version 68 | 3 69 | 70 | 71 | readme 72 | Percent Change 73 | -------------- 74 | 75 | This is an Alfred Workflow to help you do percentage calculations. You can see 76 | some background info on the original [forum post](http://www.alfredforum.com/topic/4731-percent-change/). 77 | 78 | Get the source from: https://github.com/bradmontgomery/alfred-percent-change 79 | 80 | The supported calculations include: 81 | 82 | 1. *Percent Change* (increase/decrease): `% 3 6` -> 100% 83 | 2. *Percentage Of*: 3 is what percent of 100: `% 3 of 100` -> 3% 84 | 3. *Percent Of*: 5 percent of 100 is 5: `% 5 percent of 100` -> 5, or `% 5% of 100` -> 5 85 | 4. *Percent Decrease*: What is 2 percent from 100: `% 100 - 2%` 86 | 5. *Percent Increase*: What is 100 + 2%: `% 100 + 2%` 87 | 6. *Original number before Percent Decrease*: What number is 100 2 percent less than?:`% 100 is 2% lt` 88 | 7. *Original number before Percent Increase*: What number is 100 2 percent more than?:`% 100 is 2% gt` 89 | 90 | ## Build: 91 | 92 | - Building uses the [workflow-build.py script](https://gist.github.com/AdamWagner/38228953422e830c4484e62ff116466a) 93 | bundled in this repo. 94 | - To build, run: `python workflow-build.py -f -d . -o .` 95 | 96 | 97 | ## License 98 | 99 | This Workflow is available under the terms of the MIT License. See the full 100 | [LICENSE](LICENSE.TXT) for more details. 101 | 102 | 103 | ## Contributing 104 | 105 | Contributions to this project are welcome. To contribute, feel free to fork 106 | this repo, add your changes/features/improvements, then open a pull request. 107 | Don't for get to add your name to the [AUTHORS file](AUTHORS.md). 108 | uidata 109 | 110 | ABB6BA81-8665-40FE-A867-448DF94386CA 111 | 112 | xpos 113 | 300 114 | ypos 115 | 80 116 | 117 | 118 | variablesdontexport 119 | 120 | version 121 | 1.6 122 | webaddress 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /source/percent.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # Partly cloudy ⛅️ 🌡️+43°F (feels +39°F, 22%) 🌬️0mph 🌑 Wed Mar 30 16:19:59 2022 4 | 5 | 6 | """ 7 | This is the python code for the calculations. To build the workflow, I just 8 | copy & paste this code into Alfred. 9 | 10 | Supported Calculations: 11 | 12 | 1. Percent Change (increase/decrease): `% 3 6` -> 100% 13 | 2. Percentage of; 3 is what percent of 100: `% 3 of 100` -> 3% 14 | 3. Percent of: 5 percent of 100 is 5: `% 5 percent of 100` -> 5, or `% 5% of 100` -> 5 15 | 4. Percent Decrease; What is 2 percent from 100: `% 100 - 2%` 16 | 5. Percent Increase; What is 100 + 2%: `% 100 + 2%` 17 | 6. Original number before Percent Decrease; What number is 100 2 percent less than?:`% 100 is 2% lt` 18 | 7. Original number before Percent Increase; What number is 100 2 percent more than?:`% 100 is 2% gt` 19 | 20 | Tests: To run the tests, run: 21 | 22 | python percent.py test 23 | 24 | See the bottom of this file for more details. 25 | 26 | """ 27 | 28 | __version__ = "1.6" 29 | import sys 30 | import types 31 | import json 32 | 33 | 34 | def log(s, *args): 35 | if args: 36 | s = s % args 37 | print(s, file=sys.stderr) 38 | 39 | 40 | 41 | def percent_increase(a, b): 42 | """What is `a` + `b`%?""" 43 | return str(round(a + (a * (b / 100.0)), 2)) 44 | 45 | 46 | def percent_decrease(a, b): 47 | """What is `a` - `b`%?""" 48 | return str(round(a - (a * (b / 100.0)), 2)) 49 | 50 | 51 | def percentage_of(a, b): 52 | """`a` of `b` is what percent?""" 53 | return "{0}%".format(str(round((a / b) * 100, 2))) 54 | 55 | 56 | def percent_of(a, b): 57 | """Calculates `a` percent of `b` is what percent?""" 58 | return str(round((a / 100.0) * b, 2)) 59 | 60 | 61 | def percent_change(a, b): 62 | """Given two floats, calculate the percent change and return a rounded 63 | string representation of the change.""" 64 | if a > 0: 65 | result = ((b - a) / a) * 100 66 | else: 67 | result = 0 68 | return str(round(result, 2)) 69 | 70 | 71 | def before_percent_decrease(a, b): 72 | """What is `a` `b`% less than""" 73 | percent = b / 100.0 74 | result = a / (1 - percent) 75 | return str(round(result, 2)) 76 | 77 | 78 | def before_percent_increase(a, b): 79 | """What is `a` `b`% more than""" 80 | percent = b / 100 81 | result = a * (1 - percent) 82 | return str(round(result, 2)) 83 | 84 | 85 | def parse(args): 86 | """Inspects the input arguments and calls the correct function. 87 | 88 | Returns a Tuple: 89 | (the calculated value, a human-readable version of the function used) 90 | 91 | """ 92 | try: 93 | values = '' 94 | if len(args) == 2 and type(args) == list: 95 | values = args[1].strip().split(' ') 96 | 97 | if len(values) == 2: 98 | # `% a b`. percent_change. 99 | result = percent_change(float(values[0]), float(values[1])) 100 | return (result, 'Percent Change') 101 | 102 | elif len(values) == 4 and 'percent' in values and 'of' in values: 103 | # `% a percent of b`. percent_of 104 | a = float(values[0]) 105 | b = float(values[-1]) 106 | result = percent_of(a, b) 107 | return (result, 'Percentage of') 108 | 109 | elif len(values) == 3 and values[0].endswith("%"): 110 | # `% a% of b`. percent_of 111 | a = float(values[0].strip("%")) 112 | b = float(values[-1]) 113 | result = percent_of(a, b) 114 | return (result, 'Percentage of') 115 | 116 | elif len(values) == 3 and 'of' in values: 117 | # `% a of b`.percentage_of 118 | a = float(values[0]) 119 | b = float(values[-1]) 120 | result = percentage_of(a, b) 121 | return (result, 'Percentage of') 122 | 123 | elif len(values) == 3 and '-' in values: 124 | # `% a - b%`. percent_decrease 125 | a = float(values[0]) 126 | b = float(values[-1].replace("%", "")) 127 | result = percent_decrease(a, b) 128 | return (result, 'Percent decrease') 129 | 130 | elif len(values) == 3 and '+' in values: 131 | # `% a + b%`. percent_increase 132 | a = float(values[0]) 133 | b = float(values[-1].replace("%", "")) 134 | result = percent_increase(a, b) 135 | return (result, 'Percent increase') 136 | 137 | elif (len(values) == 3 or len(values) == 4) and 'lt' in values: 138 | # `% a is b% lt` . original_number_before_decrease 139 | # `is` verb optional 140 | a = float(values[0]) 141 | b = float(values[-2].replace("%", "")) 142 | result = before_percent_decrease(a, b) 143 | return (result, 'Before decrease') 144 | 145 | elif (len(values) == 3 or len(values) == 4) and 'gt' in values: 146 | # `% a is b% lt` . original_number_before_decrease 147 | # `is` verb optional 148 | a = float(values[0]) 149 | b = float(values[-2].replace("%", "")) 150 | result = before_percent_increase(a, b) 151 | return (result, 'Before increase') 152 | 153 | elif len(values) == 1 and "help" in values: 154 | # `% help` 155 | return [ 156 | ("Increase / Decrease:", "% 3 6"), 157 | ("Add/Subtract:", "% 100 + 2%"), 158 | ("Percentage of:", "% 3 of 100"), 159 | ("Num before % increase:", "% 100 is 2% gt"), 160 | ("Num before % decrease:", "% 100 is 2% lt"), 161 | ] 162 | 163 | else: 164 | return ("What?", "I don't know what you mean.") 165 | except ValueError: 166 | return ("What?", "...") 167 | 168 | 169 | def main(): 170 | result = {"items": []} 171 | results = parse(sys.argv) 172 | 173 | if isinstance(results, tuple): 174 | title, subtitle = results 175 | result["items"].append({ 176 | "title": title, 177 | 'subtitle': subtitle, 178 | 'valid': True, 179 | 'arg': title 180 | }) 181 | 182 | 183 | 184 | elif isinstance(results, list): 185 | results = parse(sys.argv) 186 | 187 | 188 | for i in results: 189 | title, subtitle = i 190 | result["items"].append({ 191 | "title": title, 192 | 'subtitle': subtitle, 193 | 'valid': True, 194 | 'arg': title 195 | }) 196 | 197 | 198 | print (json.dumps(result)) 199 | 200 | 201 | 202 | 203 | if __name__ == "__main__": 204 | main() 205 | 206 | 207 | --------------------------------------------------------------------------------