Category: Tech
About: NYT Style COVID-19 Animated Map
The continental US heat-mapped to the previous weeks average COVID-19 cases per 100k people in each county.
Style is comparable to the current New York Times COVID-19 interactive map and use the same data source.
- Higher color number corresponds to faster spread of the virus.
- On the bottom of the map there are tools to zoom/pan/reset/save.
- Double tap the map to reset zoom/pan.
Sources
- GitHub repositories for this visualization project: Original+Legacy and Leaner animated US version.
- Produced using Python with Bokeh, Pandas, and other modules.
- Data sourced from The New York Times COVID Data GitHub Repository.
Data Defintions:
Documented at The New York Times COVID Data GitHub Repository.
Uses the rolling-averages
from us-counties.csv file, specifically the cases_avg_per_100k
data column.
Mimics the non-animated interactive map from The New York Times Online.
Errata - Map tied to possibly incorrect county data:
- Dona Ana, New Mexico, US -> Doña Ana, New Mexico, US
- New York, New York, US -> New York City, New York, US
- Bronx, New York, US -> Broome, New York, US
- Queens, New York, US -> Greene, New York, US
- Richmond, New York, US -> Rockland, New York, US
- Kings, New York, US -> Wyoming, New York, US
- Williamsburg, Virginia, US -> Williamsburg city, Virginia, US
- Emporia, Virginia, US -> Emporia city, Virginia, US
- Salem, Virginia, US -> Salem city, Virginia, US
- Portsmouth, Virginia, US -> Portsmouth city, Virginia, US
- Virginia Beach, Virginia, US -> Virginia Beach city, Virginia, US
- Danville, Virginia, US -> Danville city, Virginia, US
- Lynchburg, Virginia, US -> Lynchburg city, Virginia, US
- Falls Church, Virginia, US -> Falls Church city, Virginia, US
- Bristol, Virginia, US -> Bristol city, Virginia, US
- Hopewell, Virginia, US -> Hopewell city, Virginia, US
- Manassas, Virginia, US -> Manassas city, Virginia, US
- Waynesboro, Virginia, US -> Waynesboro city, Virginia, US
- Galax, Virginia, US -> Halifax, Virginia, US
- Martinsville, Virginia, US -> Martinsville city, Virginia, US
- Lexington, Virginia, US -> Lexington city, Virginia, US
- Norfolk, Virginia, US -> Norfolk city, Virginia, US
- Alexandria, Virginia, US -> Alexandria city, Virginia, US
- Newport News, Virginia, US -> Newport News city, Virginia, US
- Staunton, Virginia, US -> Staunton city, Virginia, US
- Charlottesville, Virginia, US -> Charlottesville city, Virginia, US
- Colonial Heights, Virginia, US -> Colonial Heights city, Virginia, US
- Petersburg, Virginia, US -> Petersburg city, Virginia, US
- Radford, Virginia, US -> Bedford, Virginia, US
- Hampton, Virginia, US -> Hampton city, Virginia, US
- Poquoson, Virginia, US -> Poquoson city, Virginia, US
- Chesapeake, Virginia, US -> Chesapeake city, Virginia, US
- Buena Vista, Virginia, US -> Buena Vista city, Virginia, US
- Fredericksburg, Virginia, US -> Fredericksburg city, Virginia, US
- Suffolk, Virginia, US -> Suffolk city, Virginia, US
- Winchester, Virginia, US -> Winchester city, Virginia, US
- Harrisonburg, Virginia, US -> Harrisonburg city, Virginia, US
- Manassas Park, Virginia, US -> Manassas Park city, Virginia, US
- Covington, Virginia, US -> Covington city, Virginia, US
- Norton, Virginia, US -> Norton city, Virginia, US
Elder Scrolls Online – Add-Ons
Installing Addons
Install the Minion Addon Manager and point it to your ESO Addon folder when prompted. For Windows running ESO through steam, the folder is under ~/Documents/Elder Scrolls Online/live/Addons/
When installing Addons, I’ll tentatively recommend simply installing all the ones you are interested in, plus dependencies and required libraries (see the descriptions in the Addons or just install all/most of the more popular ones). Then, in ESO on the initial character select screen, you can click Add-ons on the left and disable all but the addons you want to try first (or just one at a time). You can disable/enable them while online but you can’t install them while online. So this will save you some time and confusion, learn from my mistake of cluttering everything up by enabling everything at once. (You may need the Addon Selector addon and LibDialog library installed and enabled for this to work consistently whether you are logged in or not).
List of Addons I Had
Do not just blindly install all of these because some I have disabled, and some you might want elect by personal preference. See the section below on "Add-on Descriptions and Categorization".
These addons I have installed (not including libraries and dependencies). You will need check/uncheck the box to allow out-of-date addons to allow all these to function.
Below the list, I go over what I like and are important/useful. There may be some overlap between categories.
- Action Duration Reminder
- Addon Selector
- AlphaGear 2
- Assist Rapid Riding
- Azurah
- Bandits User Interface *
- Champion Point Respec
- Code's Combat Alerts
- CombatMetrics
- Constellations
- CraftStore
- DarkUI
- Destinations
- Dolgubon's Lazy Writ Creator
- Dressing Room
- EasyTravel
- Foundry Tactical Combat
- Greyskull
- HarvestMap
- HarvestMap-.... Zones
- HodorRelflexes
- Inventory Grid View
- Inventory Inaight
- LightAttackHelper
- LoreBooks
- Lost Treasure
- Map Pins
- Master Merchant....
- Miat's Stealth Text
- Minimap by Fyrakin
- Potion Maker (For Alchemy Crafting)
- RaidNotifier
- Research Assistant
- S'rendarr
- Skyshards
- Urich's Skill Point Finder
- Votan's improved Locations
- Votan's improved Quests
- Votan's Keybinder
- Votan's Lore Library Search
- Votan's Minimap
- Votan's Search Box
- Votan's Survey The World
- WeaponCharger
- WritWorthy
- YetAnotherCompass
Most have an option to make their settings account wide or to choose a character to be the template.
There are some “conflicts” between addons, meaning different addons can offer basically the same or similar functionality where you are better off turning that functionality off on all but one of them. Moreover, depending on your base game display settings etc, you may want to change/turn off some of your base game view settings to avoid duplication.
Addon Description and Categorization
These are my current preferences after going through a couple of iterations and from wanting to have the viable option of playing with a gamepad controller at times. They may not be yours. I'll list the ones I'm using and why. Then give some alternative suggestions if I have any.
I did first watch a few videos from much more experienced players and then I've culled and changed some of the choices they presented. Here are a couple of examples:
From Dottz, with an updated list of his add-ons.
From Dottz , he has many more, just search Dottz ESO Addons
on YouTube.
From Adam at Brah We Got This, beginner
From Adam at Brah We Got This, advanced
Tips Before We Begin
There is some overlap of categories so I recommend glancing through them all even if you are only looking for one. I try to avoid repeating myself.
Add-ons show up in the following places:
- Under Add-Ons on the main loading screen or when you Esc: Pick to disable/enable each add-on or library.
- Under Settings once logged in: Shows you Add-on settings/preferences and some have their own tab. You'll want to check here for each add-on you install, especially if they overlap in function and you want to turn some off.
- Under Controls once logged in: Allows you to bind keys to certain actions for some addons, e.g., to show menu screens
- When you make changes to addons, you may need to reload the UI. Usually you are warned or prompted.
Add-ons may have different behavior for different characters but most have the option under settings to unify all settings. In fact, unification of options/settings between characters is the primary feature of some addons.
To change the location/size of some user interface elements you may need to:
- Press
.
(default button) to see and move the mouse pointer and then click/drag. It can be difficult at times to find the edges of certain elements due to transparency etc. - Go into Settings for the specific Add-on and unlock movement or press a button to go into their special movement/resizing mode.
- Most of the add-ons have lots of resizing/coloring/theming/etc options and some are only be accessible through Settings in the specific settings for that add-on via sliding bars, textfields etc.
Many add-ons have similar features, such as displaying buffs and skill timers. You will most likely need to go through and turn them off in the settings for all but the one you like the best.
User Interface
- AlphaGear 2
- Bandits User Interface
- DarkUI
- Inventory Insight
- Minimap by Fyrakin Or Votan's Minimap
- Miat's Stealth Text
- S'rendarr
- WeaponCharger
- YetAnotherCompass
Bandits User Interface (BUI) has a bunch of nice UI modifications all in one and a nice central setup for those settings. Currently it is my preferred main Hud (attributes, group health) but I turn off some features I use other addons for including: Minimap and all self Buffs. BUI also has a bunch of quality-of-life features to make some various things easier, just brows through their optional settings, most of which are have good tooltips. I like the curved attributes setting with some size adjustment, set to hide them out-of-combat, and to set some alpha/transparency on some of the control. BUI has some combat statistic and a bunch of other stuff I haven't gotten into. IIRC then BUI also shows indicators on the boss health bar which are triggering for their special actions.
AlphaGear 2 allows you to setup selections of gear and skills for quick swapping. Also lets you auto repair whenever you see a merchant. Gives you a small icon on your screen that shows the current state of your gear and cost of repairs.
DarkUI setups a dark UI and gives some options. It seems nice and I think I mostly have defaults.
Inventory Insight lets you search all your banks/characters etc or a subset of them, very helpful for gaining insight into your inventory. Also lets you filter your inventory view, e.g. types of armor, and to search only through the item set names.
Miat's Stealth Text is a nice little add-on to show more clearly your status for stealth play (I might have it disabled but I think I turned it back on).
Minimap by Fyrakin or Votan's Minimap are my preferred minimaps over the one from BUI. The BUI one disappears when I use a gamepad so it is not an option for me. I find the Fyrakin one more attractive and nice, lets you keep a more immersive experience, has nice edge of map options, and it behaves consistently with/without gamepad. Votan's is solid and works with/without gamepad but it moves/changes a bit which makes it slightly inconsistent and annoying. However, Votan has lots of options and ways of making the map have different zoom levels depending on content and context. Currently, I'm using Fyrakin because its prettier, more consistent, and e.g. has the option to show all team members as icons on the minimap edge, but I'm open to Votan winning me back over.
S'rendarr is my preferred buff viewer (especially for self), it shows you a stack of all buffs/enchantments etc with the icon, timer bar, and name (helps me a lot since I don't know all the icons by heart). Has lots of options, but this is the main reason I like it and use it.
WeaponCharger automatically uses a soul stone to charge your weapon if you run out, indispenable in combat. Light and easy, a must.
YetAnotherCompass puts a compass around your crosshairs, has quite a few options to customize the compass. I like it, at least to just always show me north. BUI has reticle options but it seems to play well with YetAnotherCompass if you want to have both like I do.
Alternatives:
Azurah I have liked for general UI arrangement and some additional features, with the buffs turned off. Because BUI is so broad and clean, I chose BUI over Azurah. Also, BUI seems more consistent with/without gamepad.
Foundry Tactical Combat (FTC) is another favored option for showing attributes and other features, and for collecting combat statistics. It plays well with BUI. However, I find BUI more ascetically pleasing. You can have FTC on and just disable the attribute bars etc if you want to only use it for combat reports. I think I have it setup that way right now, but I haven't dug deep into combat reports yet.
Inventory Grid View shows your inventory in a grid and has some other options. Personally not my preference atm, partly because it doesn't necessarily play well with all other addons but some like it a lot.
Combat And Tactics
- Action Duration Reminder
- Assist Rapid Riding (currently disabled)
- Code's Combat Alerts
- CombatMetrics
- Foundry Tactical Combat (currently partly disabled)
- Greyskull
- HodorReflexes (currently not really using)
- LightAttackHelper
- RaidNotifier
Action Duration Reminder shows you action durations and reminders. Some of these features are included in other add-ons like BUI and Azurah. So you will want to make sure you are only using one for each purpose by adjusting the settings of your add-ons.
Assist Rapid Riding automatically equips and replaces special riding skills. I'm currently not using it but it seems useful and experienced players seem to like it.
Code's Combat Alerts gives alerts to special combat situations in various (non-raid iirc) PVE combat, boss mechanics and such.
CombatMetrics collects combat metrics, I use it to give me a small vertical stack display that shows me my team relative contribution to DPS and healing. Seems a staple among vets.
Foundry Tactical Combat is for when/if I get more serious about combat reports. I currently have all views disabled, but some prefer the report it can generate over CombatMetrics, so I'm keeping it for now.
Greyskull shows your current (expected?) damage output and lets you assign changes in colors depending on the number. Useful, e.g., if you are intending on not initiating a big DPS strike spike until properly buffed/debuffed. It's low profile so I keep it to help me have an idea of what my current DPS looks like but I haven't used it heavily for its primary intended purpose.
HodorReflexes is for group coordination and communication, seemingly a preferred/required add-on for serious tanks and healers (e.g. for coordinating their use of the War Horn ultimate skill).
LightAttackHelper small light weight add-on that shows statistics on your light attack use (how many and optionally the rate). E.g. helps you keep track if you are looking to make your weaving better or evaluating your animation cancelling.
RaidNotifier throws notifications about mechanics etc for raids. Haven't used it but it is probably a must at that level.
Alternatives:
Foundry Tactical Combat and Bandits User Interface both can give combat metrics.
Crafting And Research
- CraftStore
- Dolgubon's Lazy Writ Creator
- Master Merchant....
- Potion Maker (For Alchemy Crafting)
- Research Assistant
- WritWorthy
CraftStore shows you a grid of all your researched traits, what your current research progress is, and if you have slots open. Also has a bunch of other features I think but these are the ones I've used and enjoy.
Dolgubon's Lazy Writ Creator makes creating crafting writs stupid easy. Goto sign post, one click to pick up all writs. Goto crafting tables, automatically creates the writs. Turn in at the writs and it automatically opens the containers for you. Exceptions are alchemy and provisioning, where it helps but doesn't actually create for you (e.g. alchemy is non-unique of course).
Master Merchant is I think the de facto source to search guild merchant pricing etc. I haven't used this one much or quite figured it out yet, but it's supposed to be good.
Potion Maker (For Alchemy Crafting) helps you make potions. I haven't used it but it's supposed to be good.
Research Assistant is great for doing trait research and item management. Puts icons by the items you are saving for trait research indicating, e.g. if they are unique in supplying you with a source for the trait. You will need to choose a character to be your crafter for each type of crafting (a handful of categories), easy if you only have one crafter. This addon helped me to clear a bunch of inventory when I had old crappy items in my bank saved for research because of a trait, but they weren't unique. So I could get rid of most/all of the duplicate ones. In my opinion, a must for crafting/research/item-management.
WritWorthy is for evaluating if master writs are worth doing. Apparently this one had it's last update on 2020/05/20 and will not be maintained according to their webpage. I haven't used it yet but I believe it is the goto add-on for master crafters at the moment.
Map And Navigation
- Destinations
- EasyTravel
- HarvestMap
- HarvestMap-.... Zones
- LoreBooks
- Lost Treasure
- Map Pins
- Skyshards
- Votan's improved Locations
- Votan's improved Quests
- Votan's Search Box
- Votan's Survey The World
Most of these have to do with marking things on your map/s. I haven't properly gone through and sorted these so that I don't have overlapping markers. I'll only specifically mention a few.
EasyTravel lets you right click map locations to optionally travel to them (wayshrine) using friends/team/guild members automatically.
Destinations, Map Pins, Votan Improved..., have settings and pinning of things on your map.
HarvestMap lets you log all locations that you've collected resources at, e.g. flowers, wood, chests. The locations and types are optionally shown both on your map and in 3D in your view. Optionally, you can follow the directions given in the settings and download data files that give you most of the spawn points without having to manually find them yourself.
Skyshards / Lorebooks, shows the skyshard/lorebooks locations on the map but are double covered by some of the other addons here.
EDIT: After putting a little time into selecting what to see on the map and overlapping I'll add this:
Map Pins is nice but has no settings, if you go into the map using keyboard/mouse then you'll see a filter tab on the right hand side. There you can click to enable/disable all sorts of map pins. Arguably, this renders Skyshards, Lorebooks, Destinations and Lost Treasures redundant. However, some other addons may only support some of these. For example, Minimap by Fyrakin supports showing lost treasures on the map edge using Lost Treasures but seemingly not through Map Pins. You can go through on the map using Map Pins and just disable the duplicates if you like, to make it less cluttered and you can have all the listed addons enabled. Also, HarvestMap has settings (accessed by assigning a key to its settings panel) that let you sync to Map Pins so the 3D view matches the world map, or you can set them separately. So there is room for some personal preference here. I haven't looked into the performance, but it seems fine even when everything is on and super cluttered so I suggest you start by not worrying about that.
I currently have Map Pins, HarvestMap, and Lost Treasures enabled (and SkyShards, Lorebooks, and Destinations disabled). Using Map Pins I select to show only some of the pins in the map, opening the map, selecting the funnel on the left top panel, and check/unchecking items. I don't show harvesting points on the map, but I use Harvestmap to unsync with Map Pins and show in 3D view the harvest points. Then I have Lost Treasures on so that Minimap by Fyrakin shows the survey/treasures on the minmap edge (option in the minimap settings).
Other
- Addon Selector
- Champion Point Respec
- Constellations
- Urich's Skill Point Finder
- Votan's Keybinder
- Votan's Lore Library Search
Addon Selector lets you select addons to enable/disable. (This addon needs LibDialog in order to work . If you do not install the library and if you do not enable the libraries ingame in the addon manager, this addon can't be enabled and won't work)
Champion Point Respec helps you save your CP allocation and easily switch between them.
Constellations helps you calculate effects of your CP allocation partly based on parse from CombatMetrics.
Urich's Skill Point Finder shows you a nice grid of all sources of skill points and which ones you've completed. Excellent when you need to figure out where you can get some more skill points.
Votan's Keybinder lets you setup some account wide keybindings.
Votan's Lore Library Search lets you search all of your (lore) library.
Enjoy!
Keep it Simple, Private Free Podcasting
This isn't about making a secure podcast, and it's not about making a popular big podcast. It's about making a simple private but non-secure podcast for free. This is what I did when deciding to read a book for my wife because, inexplicably to me, she really loves my voice. Â This is not meant to be an idiot proof guide but hopefully if you have some rudimentary programming or scripting skills you'll find it helpful. Â If you don't, then feel free to hack away or make your life more carefree and go with lipsyn.com
I chose to use free Dropbox and to do the rest myself "manually".  The steps are:
- Record what you want to post and export to mp3 format (see other post if I get around to it).
- Create an RSS file to describe your podcast in a way podcast players understand.
- Put all your podcasting related files in a publicly shared Dropbox folder, audio files, rss (xml) file, and image files.
- Access the the rss file from a podcast app.
Lets get to it.
Setup
- Have ready your recorded files. Â Assume it's called "episode1.mp3".
- Create a square 1400x14000 pixel image file for your podcast called "mypodcast.jpg"
- Create an "index.html" file for your podcast, it can be as simple as
<html> This is my podcast </html>
Create your RSS file
Create a text file named "mypodcast.rss" and edit it.
This is a XML file so you may be familiar with the formatting from other xml files or other files with a similar format.
Enter the following text in the file:
<?xml version="1.0" encoding="UTF-8"?> <rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"> <channel> <!-- Basic info on the Podcast--> <title>The Title Of My Podcast</title> <link>the_path_to_index.html</link> <lastBuildDate>Fri, 14 Sep 2018 00:10:00 -0500</lastBuildDate> <language>en-US</language> <itunes:author>My Name</itunes:author> <itunes:summary>Summary description of my podcast</itunes:summary> <description>Description of my podcast</description> <itunes:explicit>no</itunes:explicit> <itunes:keywords>keywords for my podcast</itunes:keywords> <itunes:owner> <itunes:name>My Name</itunes:name> <itunes:email>sigthorsson@gmail.com</itunes:email> </itunes:owner> <itunes:category text="Arts"/> <itunes:image href="path_to_mypodcast.jpg"" /> <copyright>Copyright 2018</copyright> <webMaster>myemail@gmail.com (my name)</webMaster> <atom:link href="path_to_mypodcast.rss" rel="self" type="application/rss+xml"/> <item> [Stuff described in the next step] <\item> </channel> </rss>
So far, except for the file paths, everything else above is fairly self explanatory where you can put in your own descriptions and information. Â Make those substitutions.
Next replace the item field as follows:
<item> <!-- Each item: update the title, pubDate, link=guid=enclosure url (lenght=number of bytes), subtitle, summary, duration --> <!-- Episode comment, doesn't appear anywhere --> <title>My episode 1 title </title> <pubDate>Sat, 14 Apr 2018 00:30:00 EST</pubDate> <link>path_to_episode1.mp3</link> <guid isPermaLink="true">path_to_episode1.mp3</guid> <description> Description of my episode 1 </description> <itunes:author>My name </itunes:author> <itunes:subtitle>Subtitle of my episode </itunes:subtitle> <itunes:summary>Summary description of my episode</itunes:summary> <itunes:keywords>Reading</itunes:keywords> <itunes:explicit>no</itunes:explicit> <itunes:duration>00:41:51</itunes:duration> <enclosure url="path_to_episode1.mp3" length="20107307" type="audio/mpeg"/> </item>
Look at you episode1.mp3 file, find the duration of the file and the size of the file (in bytes). Â On a Mac you can get both those pieces of information by right clicking the file and selecting "Get info". Â Fill in the following
- The <itunes:duration> field in units of "hours:minutes:seconds"
- The length="..." as the size of the file in bytes, don't use ","s or "."s, just a string of digits.
This is enough for now, we'll get back to it once we've uploaded the files.
Upload to Dropbox
Create or log in to your Dropbox account.
For ease, you can install the Dropbox sync app and use a synced folder on your computer  for all your podcast files (.mp3 files, .html, and .rss)
- Upload your episode1.mp3, mypodcast.rss, mypodcast.jpg and mypodcast.html files into a Dropbox folder.
- Share the Dropbox folder and make it viewable by anyone (mouse over the folder, click the share button and select the option).
- Go into the folder.
- Mouse over each file, click the share button, click create a link.
- Copy each link name, it will have a format something like this:
- https://www.dropbox.com/s/p67vykeok9fo3fq/episode1.mp3?dl=0
- Create raw links by change substituting "/s/" with "/s/raw/" and removing the "?dl=0", example:
- https://www.dropbox.com/s/raw/p67vykeok9fo3fq/episode1.mp3
Add Links To The RSS File
Take all the shared links you recorded in the previous step and update the mypodcast.rss file. Â Replace all the "path_to_..." files with the appropriate Dropbox raw links.
Make sure the mypodcast.rss file in Dropbox is synced with the mypodcast.rss file you just edited.
Accessing Your Podcast
Go to your favorite Podcast app, like Overcast, and use the raw link you created earlier for mypodcast.rss and add it as a podcast feed.
Done!
Your podcast should now be working and coming up on your Podcast app with the icon image for your podcast and your one episode listed with it's title showing.
Adding More Podcast Episodes And Additional Notes
To add more episodes simply do the following:
- Record a new audio file, "episode2.mp3"
- Upload the file to Dropbox and create a raw link as before.
- Create the text for an <item> for episode2 as described before for episode1, updating the path, title, duration, and length for the file.
- Add the text below the <\item> for the previous episode.
- Don't forget to set the correct (or desired) date and time for the episode
- Update the <lastBuildDate> to the current date time (this should trigger the Podcast app to actually check the rest of the rss file and show you the new episode).
- Make sure the .rss file is synced.
Student Loan Calculator
Student Loan Calculator - Documentation
(Version 1.0)
The Student Loan Calculator is intended to help with student loan repayment planing when things are not just simple and static. For professions such as physicians with federal loans, income based repayment may be available with loan forgiveness at the end of the initial loan period. Physicians are also commonly expected to have a huge jump in their income level at some point during the original loan period. I have come in contact with some misleading information around these topics and often “back-of-the-envelope” calculations fail to capture the basic scope of the problem.
I’m not a financial expert, I’m not giving any official financial advice, but I am an engineer, scientist, and proficient at maths. My family and I have some skin in this game of student loans and I got tired of getting half answers and relying on just intuition despite good success. Therefore, I created this little tool to help get some reasonable financial estimates and gain some insight into problems similar to mine and perhaps also yours. It’s not a perfect tool but I think the estimates are good enough to inform some of my personal and family financial decisions.
After describing the loan parameters, the following repayment plans are considered
- Minimum Repayment Plan
- Aggressive Repayment Plan
- Aggressive Two Phase Repayment Plan
- Income Based Repayment Plan With Possible Loan Forgiveness
Comparison Results of the repayment plan calculations are presented in a small graph.
Saving/Investment comparisons are also presented
- Savings Comparison 1 (minimum number of extra payments)
- Savings Comparison 2 (maintain extra payments)
The link below the “Comparison Results” section provides a url link with your current settings of the calculator that can be used to save or share results.
The following sections describe the repayment plans and the workings of the calculator.
Standing Assumptions / Comments
- Any extra loan payments are assumed to go towards paying (lowering) the principal of the loan
- THIS IS VERY IMPORTANT: If you are paying more than the minimum payments on your loans, make sure that those payments are going towards the principal of the loan. Some lenders may default to putting the extra payments towards future interest which doesn’t help you pay off the loan faster or more efficiently in most all cases.
- The pay-period is a month, i.e., 12 pay-periods per year. So payments are made every month and interest is calculated every month (APR/12).
- Unless otherwise stated, parameters such as payments per month and interest rates are assumed fixed.
- Interest is normally calculated as compound interest.
- For the saving/investment and loan projections.
- The only exception currently is a presentation of a special case shown in the “Other Results/Warnings/Comments:” textbox: if the phase 1 income based repayment plan monthly payment is less than the current interest.
- All text input entries are expected to be positive numbers with “.” as the decimal point and no other characters. Example: a loan principal of $200,123.11 loan should be entered as 200123.11 in the Current Loan Principal field in the Loan Parameters section. The calculator won’t yell at you if you do something wrong, like entering letters or zero or negative or non standard numbers, the results will just be garbage, e.g. NAN, negative numbers, nonsense.
- Another programming note, weird things can happen if you set a rate to zero so if you want to look at such cases (not sure why) then just set the rate to an extremely low value to estimate the results (e.g. 0.0001% will be fine, too close to zero and you’ll see numerical issues arise).
Loan Parameters
The parameters are:
- Current Loan Principal
- The current principal of the loan
- If you have multiple loans, then this should be the sum of the principals
- Loan APR
- The annual interest rate of the loan
- The APR is assumed to be fixed
- If you have multiple loans, then you can estimate the APR as the weighted average of the loans (e.g. loan one is for $10,000 at 4%, loan two is for $20,000 at 6%, then the weighted average is (10000x4+20000x6)/(10000+20000)=5.33%
- Keep in mind that if one loan has significantly higher interest than another, then if you pay more than the monthly minimum payment, pay it towards the highest interest loan. This will lower your total payment on aggressive repayment plans.
- Loan Period
- The period of the loan
- If you are unsure of the period and are currently not in any special repayment program, then your minimum payment should be set such that you will pay the loan off on time.
- If the above applies, then you can estimate the period of the loan by tweaking the loan period until you get your minimum monthly payment in the Minimum Repayment Plan section.
Repayment Plans
Minimum Repayment Plan
This is the nominal plan if you can afford it.
There are no editable parameters.
The calculated fields are:
- Min Monthly Payment
- The minimum monthly payment which makes you to pay off the loan on time.
- Throughout this document, when referring to the minimum monthly payment or original minimum monthly payment then this is that amount unless otherwise explicitly stated.
- Total Paid
- The total amount you will pay on this plan.
Aggressive Repayment Plan
This is likely the best plan if you can afford more than the minimum payment.
The parameters are:
- Extra Payment
- The amount you plan to pay every month that exceeds the monthly minimum payment.
- These payments go 100% towards lowering the principal of the loan.
The calculated fields are:
- Monthly Payment
- The extra payment plus the minimum monthly payment.
- Loan Paid In
- How long it will take to pay off the loan under this plan.
- This will be shorter than the loan period.
- Total Paid
- The total amount you will pay on this plan.
Aggressive Two Phase Repayment Plan
This is the same as the aggressive plan but in two phases. If you expect to have a huge jump in income during the loan period, you are likely to be able to afford to pay more at a later date.
For example, if you are a physician resident earning a 1/4 of your minimum expected pay in 3–5 years.
If you have a drop in disposable income during your loan period, you may afford to pay less extra at a later date.
For example, due to foreseeable life events such as loss of employment, relocation, or expanding your family, all of which may reduce your disposable income. These cases can also be modeled here by lowering the extra payment or possibly taking advantage of a lower minimum monthly payment needed to complete paying off the loan on time, assuming the terms of your loan allows for that (they should, assuming you were allowed to pay towards the capital of the loan).
The editable parameters are:
- Phase 1
- Extra Payment
- The amount you plan to pay every month during phase 1 that exceeds the monthly minimum payment.
- Period
- How long you will apply the phase 1 extra payment.
- Extra Payment
- Phase 2
- Extra Payment
- The amount you will pay every month during phase 2 that exceeds the monthly minimum payment for phase 2
- The original minimum monthly payment is more than the minimum monthly payment for phase 2 if the phase 1 extra payment is greater than 0.
- Extra Payment
The calculated fields are:
- Phase 1
- Monthly Payment
- The extra payment plus the minimum monthly payment.
- Total Paid
- The total amount you will pay on this plan during phase 1.
- Loan Principal Remaining
- The loan principal remaining after phase 1
- Monthly Payment
- Phase 2
- Adjusted Monthly Payment
- If the extra payment in phase 1 is greater than 0, then the principal of the loan is less than it would be applying the original minimal payments.
- This is the minimum monthly payment needed to pay the loan on time according to the loan period, given that phase 1 has paid off more than the minimum.
- Monthly Payment
- The extra payment plus the adjusted minimum monthly payment.
- Total Paid
- The total amount you will pay on this plan during phase 2.
- Adjusted Monthly Payment
- Results:
- Loan Paid In
- How long it will take to pay off the loan under this plan.
- This will be shorter than the loan period.
- Total Paid
- The total amount you will pay on this
- Loan Paid In
Income Based Repayment Plan With Loan Forgiveness
Some loans allow for income based repayment, possibly lower than the minimum payment on the loan in order to pay it back on time. Furthermore, if there is a remaining balance at the end of the loan period, that balance is forgiven. For example, a physician may work for a non-profit organization and at the end of the loan period, may have been working there long enough to qualify for loan forgiveness.
The motivating example for this is if a person has the option to live frugally enough to make extra payments but might also qualify for forgiveness. What will allow for minimum total payment? Will faster repayment be sufficient to result in a lower overall payment than to take advantage of potential forgiveness at the end of the loan period.
Special Case: If the income based repayment is less than the interest being accrued on the loan, then the nominal case is that the unpaid interest is added to the principal. In the “Other Results/Comments/Warnings” text field, an alternative case is computed where the remaining interest is forgiven. There are certain loans and repayment plans that correspond to this case. There are also loans where 50% of the remaining interest is forgiven but that case is not considered here. The total payment for such a loan will be somewhere between the nominal and the interest forgiven cases that are considered.
The editable parameters are:
- Federal Poverty Level Income
- Used for calculating the income based repayment
- In 2017: about $12,060 for individuals, $16,240 for a family of 2, $20,420 for a family of 3.
- Source
- Income Based Repayment Rate
- Used for calculating the income based repayment
- Probably either 15% or 20%, depends on the program and loan
- Phase 1
- Adjusted Gross Income
- From your tax forms, the adjusted gross income for yourself and your spouse (even if you file separate tax returns).
- Period
- How long the phase 1 adjusted gross income applies
- Adjusted Gross Income
- Phase 2
- Adjusted Gross Income
- From your tax forms, the adjusted gross income for yourself and your spouse (even if you file separate tax returns), after the phase 1 period.
- Adjusted Gross Income
The calculated fields are:
- Phase 1
- Monthly Payment
- Monthly payment during phase 1.
- The lesser of:
- The minimum payment
- The income based monthly repayment, which is:
- (Adjusted gross income - Federal Poverty Level)*(Income Based Repayment Rate)/12
- Total Paid
- The total paid during the phase 1 period.
- Loan Principal Remaining
- Amount remaining of the principal after the phase 1 period.
- If the phase 1 monthly payment is less than the interest of the loan, then the interest remainder is added to the principal each month.
- Monthly Payment
- Phase 2
- Adjusted Min Monthly Payment
- The minimum payment needed after phase 1 to pay the loan on time.
- If phase 1 resulted in a monthly payment less than the minimum payment, then this will be greater the original minimum payment.
- According to phone calls with federal student loan officers/advisors, this is how adjust income repayment plans work for those loans.
- Monthly payment
- Monthly payment during phase 2.
- The lesser of:
- The adjust minimum monthly payment for phase 2
- The income based monthly repayment, which is:
- (Adjusted gross income - Federal Poverty Level)*(Income Based Repayment Rate)/12
- If your income goes up sufficiently, then provided that the adjusted minimum payment is lower than the income based monthly payment, your payment will go up to the point of paying the loan off on time and there will be no remaining balance to forgive.
- Total Paid
- The total amount paid during phase 2
- Adjusted Min Monthly Payment
- Results
- Total Paid
- The total amount paid during both phase 1 and 2
- Amount Forgiven
- The remaining loan balance after phase 2
- This amount is assumed to be forgiven and not accounted for in comparing the payment plans
- Note that the total paid amount is the number you’ll be more interested in. If you end up paying more than on a different plan that you find feasible, then the amount forgiven is really irrelevant, and the financially superior plan is the one with the lower total amount paid.
- Total Paid
Compare Results
Total Payments
The length of the bars shown are proportional to the total amount paid under each repayment plan, as indicated by the text on each bar. The text at the end of the bar restates the amount.
This allows for a quick comparison of the total amount paid under all the plans and helps evaluate which one fits your finances best, or if the differences are small enough for you to rather be guided by other life goals.
Savings/Investments comparisons are also made and are discussed in the next section.
Saving/Investment
The editable parameter is:
- Savings/Investments APR
- The annual rate of return on you savings/investments
- As a rule of thumb you can guesstimate:
- 0.x% for savings accounts
- 1% for CDs
- 2–3% for bonds
- 5–10% for index funds (over long multi year horizon)
- Retirement savings (e.g. 401k/Roth) are usually a mixture of bonds and market funds but also have some extra tax incentives and possibly employer matching.
- If you have the chance to get employer matching towards a retirement fund, then that is 50–100% multiplier on the money you put in. This is most always going to be your top priority over paying more than a minimum on long term loans or paying into other savings.
Savings Comparison 1 (minimum number of extra payments):
This is attempting an apples-to-apples comparison given that you can afford the aggressive repayment plan and that you can sustain paying the original minimum payment throughout original loan period.
For example, if you can afford the minimum repayment plan throughout the loan period but are able to live extra frugally for a while and execute the aggressive plan. How much will you have saved on each plan if you put your extra funds towards savings/investments.
The length of the bars show the savings accumulated on each plan according to the list below. The text shows the total savings.
- The Minimum
- During the time that the aggressive plan is paying off the loan, payments are made towards savings equaling the extra payment amount for the aggressive plan.
- Thus, during the first few months/years of the loan, while the aggressive is paying off the whole loan, payments are being made here to savings. Those savings then earn compound interest until the end of the original loan period without further additional payments.
- The Aggressive
- After loan is paid off, payments are put into savings each month equaling the original minimum loan payment until the end of the original loan period
- Thus, no payments are made towards savings during the time the loan is being payed off. But after that, payments are made towards savings and those savings earn compound interest.
Savings Comparison 2 (maintain extra payments):
This is attempting an apples-to-apples comparison assuming you can afford the aggressive repayment plan throughout the original loan period.
For example, if you can afford the aggressive repayment plan throughout the original loan period: How much will you have saved on each plan if you put your extra funds towards savings/investments throughout the original loan period.
The length of the bars show the savings accumulated on each plan according to the list below. The text shows the total savings.
- The Minimum
- During the loan period, payments are made towards savings equaling the amount of extra payments under the aggressive plan.
- The savings earn compound interest throughout the loan period.
- The Aggressive
- After loan is paid off, payments are put into savings each month equaling the aggressive monthly payment until the end of the original loan period.
- Thus, no payments are made towards savings during the time the loan is being payed off. But after that, an unchanged amount of monthly payments are made towards savings and those savings earn compound interest.
Keep it simple, Javascript and Mobile Safari iOS Audio
I had  my little workout timer app all written out nice and neat, with little beeps for breaks and starts.  But I heard nothing on my iPad.  I find out mobile Safari doesn't support automatically played audio, it must be initialized by the user. Soon after, I see there are ways around the limitation.  With other people providing more details.  My thanks for their help and input which I rely on below.
I wanted it simple and "easy", so I boiled it all down.
The basic audio limitations of Mobile Safari:
(see more details in the links above)
- Can only start play from a user prompt like a "onclick" event .
- Only allows one audio file loaded at a time.
The basic workarounds are:
- Push Once: Make the user push a button just once.
- Never Stop:  After that first click, use play, pause, and adjust playback time however many times you like.   But never actually finish playing the whole audo file.
- Use Sprites: Use audio sprites, i.e. use one audio file with all the clips you want to play in one file and keep track of at what time each clip is located an how long it is.
Creating the Audio
Using Audacity or other audio editor, record/combine/edit/track your audio clips all together in one file such that:
- First 1 sec is silence.
- Keep track of where each clip starts and how long it is, leaving at least about 0.5sec of silence between clips.
- End with 1sec of silence.
Export the audio sprites file to a compatible format, e.g., Â .mp3 or .m4a (I used .m4a in the example).
The Code
The HTML includes assigning the audio source (here the file is named "12345.m4a")
[code language="html"]<audio id="audio"> <source src="12345.m4a" type="audio/mp4" /> </audio>
[/code]
The Javascript has the following commented setup near the top.  The "spriteData" contains the names of the clips/sprites, their start time in sec, and their length.  This particular audio sprite file is a sequence of counts from one to five, each starting at their respective second and 0.5sec long.  The "currentSprite" will be used to keep track of the current sprite begin played or most recently played.
[code language="javascript"]// Audio Sprite Setup
// Get the sprite element
var audioSprite = document.getElementById('audio');
// Assign the sprite data (field names for id, start time of the clip in sec and length in sec)
// Place a silence at the beginning and end of the clip (about a second each) as a buffer to avoid undesired playback or termination due to inaccuracy in audio timing due to the browser
var spriteData = {
// Always have the first second silence and named "silence"
silence: {start: 0.0, length: 0.5},
one: {start: 1, length: 0.5},
two: {start: 2, length: 0.5},
three: {start: 3, length: 0.5},
four: {start: 4, length: 0.5},
five: {start: 5, length: 0.5}
};
// current sprite being played
var currentSprite = {};
// End Audio Sprite Setup
[/code]
Then somewhere below it has the remaining setup for playing the sprite, commented for clarity.
[code language="javascript"]// AUDIO SPRITE HANDLING
// time update handler to ensure we are in the current sprite and stop when it is complete
var onTimeUpdate = function() {
var timing_tolerance = 0.2; // .currentTime is not accurate, set this as the tolerance for its inaccuracy
// If at the end of the current sprite, then pause
if (this.currentTime >= currentSprite.start + currentSprite.length) {
this.pause();
}
// If playing but not in the current sprit, then go there (this can occure due to iOS timing issues and start playing from the start of the sprite file unintentionally)
else if (this.currentTime < currentSprite.start-timing_tolerance) {
audioSprite.currentTime = currentSprite.start;
}
};
// Set listener for timeupdate to have the currentTime be in the current sprite
audioSprite.addEventListener('timeupdate', onTimeUpdate, false);
// in mobile Safari, the first time this is called will load the audio. Ideally, we'd load the audio file completely before doing this.
// This function needs to be called first from a user touch event such as onmousedown, onmouseup, onclick, or ontouchstart.
var playSprite = function(id) {
if (spriteData[id] && spriteData[id].length) {
currentSprite = spriteData[id];
audioSprite.currentTime = currentSprite.start;
audioSprite.play();
}
};
var playSpriteInitialize = function(){
playSprite('silence');
// Whatever code you want first executed
//...
};
[/code]
That's all. Â As long as "playSprite" or "playSpriteInitialize" are called using a button first (or other compatible event), then the sprites can be played programmatically from that point on using
[code language="javascript"]playSprite["name_of_clip"][/code]
Note that the "currentTime" is not accurate to within about 0.2 or maybe even more seconds. Â So this solution may have some limits if vary rapid audio transitions are needed.
Example
Here is a little code snip wrapped with HTML/CSS to play a count from 1 to 5 using text and audio. Â The proof of concept is in that once you push the start button once, the program is able to use "setInterval" to automatically/programmatically play the count from the audio sprite file.
Here is the complete code for the example:
[code language="javascript"]
<!DOCTYPE html>
</html>
<audio id="audio"> <source src="12345.m4a" type="audio/mp4" /> </audio>
<button onclick="start_count();">Start Counting</button>
<button onclick="stop_count();">Stop Counting</button>
<div id="count_txt"> --- </div>
<script>
// Audio Sprite Setup
// Get the sprite element
var audioSprite = document.getElementById('audio');
// Assign the sprite data (field names for id, start time of the clip in sec and length in sec)
// Place a silence at the beginning and end of the clip (about a second each) as a buffer to avoid undesired playback or termination due to inaccuracy in audio timing due to the browser
var spriteData = {
// Always have the first second silence and named "silence"
silence: {start: 0.0, length: 0.5},
one: {start: 1, length: 0.5},
two: {start: 2, length: 0.5},
three: {start: 3, length: 0.5},
four: {start: 4, length: 0.5},
five: {start: 5, length: 0.5}
};
// current sprite being played
var currentSprite = {};
// End Audio Sprite Setup
// DEMO ------------------------------------------
var myTimer = {}; // Initialize variable used for timers
var counter = 0; // Initialize counter
var Ncounter = 5; // Up to how many counts
// Assign audio sprite according to the counter, and increment
function sound_count(){
var ids = ["one","two","three","four","five"]; // Array of the sprite names
counter = (counter%Ncounter); // make sure counter is in bounds
playSprite(ids[counter]); // play sprite
document.getElementById('count_txt').innerHTML = ids[counter]; // show counter
counter++; // increment counter
}
// Start a count on a timer
function start_count(){
clearInterval(myTimer); // Clear timer if in case it was already running
myTimer = setInterval(sound_count,1000); // Set timer to run the sound count every 1000ms
}
// End a count
function stop_count(){
clearInterval(myTimer);
}
// End DEMO ------------------------------------------
// AUDIO SPRITE HANDLING
// time update handler to ensure we are in the current sprite and stop when it is complete
var onTimeUpdate = function() {
var timing_tolerance = 0.2; // .currentTime is not accurate, set this as the tolerance for its inaccuracy
// If at the end of the current sprite, then pause
if (this.currentTime >= currentSprite.start + currentSprite.length) {
this.pause();
}
// If playing but not in the current sprit, then go there (this can occure due to iOS timing issues and start playing from the start of the sprite file unintentionally)
else if (this.currentTime < currentSprite.start-timing_tolerance) {
audioSprite.currentTime = currentSprite.start;
}
};
audioSprite.addEventListener('timeupdate', onTimeUpdate, false);
// in mobile Safari, the first time this is called will load the audio. Ideally, we'd load the audio file completely before doing this.
// This function needs to be called first from a user touch event such as onmousedown, onmouseup, onclick, or ontouchstart.
var playSprite = function(id) {
if (spriteData[id] && spriteData[id].length) {
currentSprite = spriteData[id];
audioSprite.currentTime = currentSprite.start;
audioSprite.play();
}
};
var playSpriteInitialize = function(){
playSprite('silence');
// Whatever code you want first executed
//...
};
// End Audio Sprite Setup
</script>
</html>
[/code]