Retirement Plans:

There are a host of retirement plans available in USA to save you taxes. You can save money yourself, and invest in any investment of your choice, instead of going thru the hassle of retirement accounts, but then you don't get any tax break. These specifically designed retirement accounts save you on taxes. Of all the plans out there, 401K retirement plans are the best retirement plans to shove all your money in. Only when you have maxed out your 401K plan, should you consider other plans. Let me give you a brief introduction of various plans available to you. All retirement accounts are per individual, so if you are married, then both you and your spouse can have their own retirement accounts.

For all the retirement accounts, you are only allowed to contribute if you are working (i.e have a W2 income). If you are not working and are having passive income from CD, stocks, etc, you are not allowed to contribute to any retirement account. Also, Retirement accounts do not have a concept of family, they are meant for the individual person, and that person needs to have earned income in order to contribute to his/her retirement account. There is however one exception to this : A family where one of the spouse is not employed is still allowed to have a spousal retirement account. Since one of the spouse doesn't have an income, the other partner is allowed to contribute to the retirement account of spouse, provided the other partner has earned income. The rational behind allowing a spousal retirement account is that the non working spouse is taking care of the family/kids, and so would be left with nothing in retirement just because he/she is not working.

 

various retirement plans

1. 401K plan:


The retirement plan got its name from its section number and paragraph in the Internal Revenue Code -- section 401, paragraph (k). It was enacted into law in 1978. Final regulations were published for it in 1991. This plan is offered by your employer. You can enroll in this plan when you join a job, as most of the employers offer this plan. Once you enroll in the plan, a set amount of money (whatever you indicate on your enrollment form) gets deducted from every paycheck. Your employer usually hires a Trustee to hold the assets of 401K plan. (for ex fidelity may be one such trustee). You usually don't pay any fees to the trustee, since your employer pays for any kind of fees. However, recently I've started seeing some of these trustees deducting plan management fees from their clients accounts (usually $100/year or something like that for basically doing nothing, and your employer forcing you into having an account with that trsutee).  In such cases, complain to your employer and ask them to pay for any such fees, or allow you an option to choose a trustee of your choice.

There used to be only 1 kind of 401K plan until 2006. It used to be called 401K, or traditional 401K. But since 2006, govt allowed other type of 401K plan called as Roth 401K plan. I'll discuss only traditional 401K for now, and discuss Roth 401K later. All info below is for traditional 401K plan unless noted otherwise.

Qualifications:

1. Employed: The most important requirement for this plan is that you have to be employed and be receiving a paycheck large enough to cover your contributions to your 401K plan. For ex, if you want to contribute $1K per paycheck, you should have an income in that paycheck for more than $1K, and do a direct deposit from your paycheck to your 401K account. You can't contribute to 401K any other way (i.e transferring money from your bank account, or sending a check). However, on the positive side, you can change your contribution to 401K account any time. So, if you feel that you want to contribute more in the second half of the year because you contributed too low in the first half of the year, just change the amount of contribution on your trustee's website. If you are without a job for let's say 2 months, you cannot make any contribution to your 401K while you are out of job, but once you get your job back, you can start contributing again.

2. Limit.  There is no income limit for contributing to 401K. i.e you can make millions of dollars and still contribute to the maximum amount allowed. Most of the other retirement plans have an income threshold beyond which you are not allowed to contribute to that plan, but NOT for 401K. That is why 401K is the first choice for a retirement account. However, there's an annual limit on the amount of money you can contribute. It increases every year and is announced by IRS in advance. For 2009, it was $16,500. For 2020, it's $19,500. If you are age 50 or older by year end, then you are eligible for an additional catch up contribution for that year (for year 2020, this additional limit is $6500, so anyone over 50 can contribute a total of $19,500+$6500=$26K for year 2020). This money is contributed tax free (or in other words, it's deductible from your salary to determine taxable salary). That means your salary is deducted by your 401K contribution amount, before any federal/state taxes can be calculated on it. However, you still pay social security and medicare taxes on this amount (which is about 7.5% of your contribution amount). One side advantage of putting money in 401K is that your Adjusted Gross Income (AGI) gets reduced by the amount you contributed to 401K. Your AGI determines your eligibility for many kind of tax credits and tax breaks, so by putting yourself in a lower income range, you may avail of many other tax savings. That's an indirect benefit of contributing to a 401K account.

  • 2023 Limits = $23K  (+ $7K for > 50 yr old).

Benefits:

Employer match: To top it, your employer also matches a certain portion of your contribution to your 401K account. Typically, employers match anywhere from 50% to 100% of your contribution up to a maximum amount. So, let's say if you contribute 10% of your salary to 401K, the employer may match 50% of your contribution for the first 6% => i.e putting extra 3% of your salary in your 401K account. This is absolutely free money. However, it's done for every paycheck, so if you missed getting 3% from your employer for a certain paycheck (because you just joined a job and 401K is not setup, or you lowered your contribution, so that you are not able to maximize your employer's contribution), then you cannot do a catch up for your employer contribution. Many times people contribute too much to their 401K amount in the first few months, and then in the last few months, they can't contribute anything because it goes over the contribution limit. In such a case, you lose your employer's match for those months. In all such cases, that employer contribution is lost for ever for those few months. There is nothing anyone can do retroactively. So, be careful with 401K accounts whenever you change your contribution amounts. Make sure that you can maximize your employer contribution (since it's free money). I've lost this free match for multiple months, whenever I readjusted my contribution limit (since sometimes I get bonus which also get contributed to 401K resulting in my contribution going over the limit. By the time I realize this, it's too late). Just recently, I came to know that there is an option on some of these "retirement trustee websites, where you can choose the option to "maximize employer contribution", as well as "maximize my contribution". That way, it will always readjust to make sure you never lose your employer contribution, no matter how wildly your paycheck varies from month to month. Never choose "fixed % contribution" as 6%, 10%, 15% etc as that will land you in NOT getting "maximum employer match". 

Just as you as an employee have a contribution limit, your employer also has a contribution limit. It varies from year to year. For 2020, the maximum contribution limit to 401K from all sources in $57K (or $63.5K if age 50 or above). Since your contribution limit is $19.5K, that means your employer can match only up to $57K - $19.5K = $37.5K. I don't know of any employer matching more than 6%, so in order to exceed that threshold, you will need to have a base salary of more than $300K (at $300K, you contribute 6% and your employer contributes 6% for a total of $36K). So, for most of the employed out there, you will never exceed this $57K threshold, so don't even bother about it.

Tax free Growth:

Your contribution as well as your employer's contribution goes into your 401K account, and the money grows tax free till it is withdrawn. Your withdrawals are taxed at ordinary income tax rate at the time of withdrawal, provided you have reached 59 1/2 years of age. If you withdraw any of this money before reaching 59 1/2 yrs, you have to pay an additional 10% penalty.

Changing employers:

I've gotten bitten by it, so I should share this. When you change employer (due to job change), you can either leave your 401K retirement account at old trustee, or you can move it to new trustee (wwhover is the new trustee with your new employer), or you can just open a new Roll over IRA account at any brokerage firm, and transfer your 401K portfolio to the brokerage firm. I would advise to move your 401K account to Roll Over IRA account at any brokerage firm of your choice. There are multiple advantages to this as noted below:

  • Almost always, your company trustee charges you a yearly maintenance fee for keeping your account. In many cases your emplyer pays that fee and you don't see it (in some cases, you have to pay that fee as your employer may not be paying that fee). But when you leave your current employer, the trustee will start charging you that fee, and may even raise that fee. You are at the mercy of that trustee. There is no reason to pay any fees to these trustees.
  • When you move your 401K account to a brokerage firm, they will usually give you a handsome bonus for bringing the 401K to them. They also don't charge any fee of any kind. So, you make money 2 ways - first by getting the bonus, and secondly by not paying any fees.
  • You can keep changing brokerage every few years to take advantage of bonus amounts that they give. This can easily net you about $1K per year in bonuses, just moving your roll over IRA accounts.
  • With discount brokerage firms, you have the option to invest in any stock or fund you want. With your company's trustee, you may have very limited choices, and they may even charge you higher expense ratio for these funds. With discount brokerage, you pay no transaction fee, and expense ratio for ETF are as low as 0.02%.
     

2. IRA (Individual retirement account):


These are called individual accounts because any individual can open one and contribute to it. (these are outside of any corporate retirement plan). These accounts are owned by you, and you decide where to open these accounts or move them to other bank/brokerage on your will at any time. These accounts can be opened on top of 401K accounts discussed above. You are free to invest the money in any way you like in these IRA accounts. You can setup this IRA account at any brokerage firm (i.e Schwab, etc) or you can open a savings IRA account or a CD at any bank. You should always open an IRA account at a brokerage firm, as they charge you no fees of any kind, and will generally give you a bonus for opening or transferring your IRA account to them. Then you can buy stocks in these IRA accounts. You can open any number of IRA accounts, but the total amount of money that you can put in all of them combined is limited as per IRS limits for that year. For year 2009, the limit was $5K (+$1K additional catch up for age 50, for a total of $6K). For year 2020, the limit was $6K (+$1K additional catch up for age 50, for a total of $7K). You can contribute to the maximum amount, but you may not be able to deduct all of it. You may be able to deduct all or part of it in your tax returns depending on your participation in 401K and your income.

If you are not contributing to a workplace 401K account, then you can deduct (in your tax return) up to the contribution limit irrespective of your income. However if you or your spouse is participating in a workplace 401K account, then there is an income limit. If you are above the income limit, then neither you nor your spouse can deduct the full contribution amount from federal tax returns. The limit is based on MAGI (modified adjusted gross income). MAGI is adjusted gross income with some deductions and exclusions added back in. For a married couple filing income tax jointly in 2020, the MAGI limit was $104K. That means if your joint tax return had a MAGI of < $104K, then both you and your spouse can contribute and deduct up to $6K (or $7K if over age 50). Then two of you combined can contribute $12K (or $14K if over age 50). Assuming you are in 25% tax bracket, you can save about $3K on taxes. However, the amount you save in taxes is dependent on type of IRA plan. If your MAGI is in between $104K to $124K, then you can deduct your contribution only partially, while if your combined MAGI is > $124K, then you can deduct nothing. These limits apply only if both spouses are working and are participating in 401K plan.

However, if one of the spouse is not working, then higher MAGI limits are allowed. For 2020, this MAGI limit was $196K. That means if your joint tax return had a MAGI of < $196K, then both you and your spouse can contribute and deduct up to $6K (or $7K if over age 50). Then two of you combined can contribute $12K (or $14K if over age 50). If your MAGI is in between $196K to $206K, then you can deduct your contribution only partially, while if your combined MAGI is > $206K, then you can deduct nothing.

There are 11 flavors of IRA plan. However, we'll discuss 2 most common ones.

A. Traditional IRA: These are Traditional and as such you don't pay federal/state taxes right now on this contribution, but pay them at time of withdrawal. The withdrawals are taxed as ordinary income. Besides, there'a 10% penalty if withdrawn before age 59 1/2 yrs. You can setup tax deductible or non-tax deductible traditional IRA. Non-deductible traditional IRA are pretty much useless, so we'll only talk about tax deductible traditional IRA.

B. Roth IRA: Under this IRA, any contributions you make are not tax deductible. You contribute money to this plan after taxes have already been deducted. However, you can withdraw the money tax free after age 59 1/2. So, it's kind of opposite of traditional IRA. In traditional IRA, you weren't taxed upfront, but were taxed on withdrawal. For Roth IRA, you are taxed upfront, but are not taxed on withdrawals. For year 2010, income limits were around 120K for singles, and $180K for married couples to be eligible to contribute to a Roth IRA.

NOTE: you can open any number of the above IRA accounts, but the total amount you can contribute and deduct is limited to the contribution limit for that year. Many people open both Traditional and Roth IRA and contribute to both of them, but total contribution can't exceed $6K for 2020 across all these IRA accounts combined. You may contribute more, The deduction you can take for contributing to these accounts is based on your MAGI. If your MAGI exceeds a certain threshold, then there's no point contributing to these IRA accounts, as you won't get any tax break. In such a case, you should just invest any savings by putting it in your personal brokerage account. The deduction limit goes up every year, although much more slowly than the limit for 401K account. Married people can have slightly higher tax deductible contribution. The limits go up a little bit every year depending on inflation.

 


 

Should you invest in retirement plan and if so, which retirement account?

401K: The top choice for retirement plan is 401K plan. You should contribute to a 401k plan up to the max limit allowed. Why is that beneficial? Because you don't pay any taxes on those amounts now, you pay taxes when you withdraw money in retirement. This equates to 0% long term tax rate on those earnings. If you were to take out that money and invest it in non-retirement account, you would get hit with 15% long term tax. Let' see how:

Let's consider an example where you have $10,000 to invest either in 401K or pay taxes and take it out, and invest it in personal non retirement account. Remember, that in retirement account, all of your money including your capital gain is taxed at your personal income tax rate (no long term capital gain tax rate allowed), while the money kept in your personal non retirement account is subject to lower long term capital gain tax rate (if held for > 1 yr). So, that helps, but not enough in most cases to offset the retirement account benefit.

CASE A: Assume you are in 25% tax bracket now, and in retirement too. There is 15% long term capital gain tax rate in effect.

scenario 1: Money invested in 401K in XYZ fund, and then taxed when withdrawn (assume no penalty as it's withdrawn after 60)

money to invest after taxes (tax 0%) money growth in XYZ fund (8%/yr) money after 30 yrs tax on withdrawing (25%) net money after 30 yrs
$10,000 $10,000 $90,000 $100,000 $25,000 $75,000

scenario 2: Money taken out and invested yourself in XYZ fund. You have to pay taxes before you can invest that money, as there's no deduction. So, money invested is lower at the beginning because of Uncle Sam's tax portion.

money to invest after taxes (tax 25%) money growth in XYZ fund (8%/yr) money after 30 yrs tax on withdrawing (15%) net money after 30 yrs
$10,000 $7,500 $67,500 $75,000 $67,500*0.15=$10,125 $65,000

As you can see in tables above, scenario 1 results in 15% more money than scenario2, as scenario1 resulted in effective 0% long term capital gain tax rate, while scenario 2 resulted in 15% long term capital gain tax rate.

 

CASE B: If we assume that we go in higher tax rate bracket in retirement, then the difference gets smaller. If the long term capital gain tax rate gets smaller in future (<15%), then our scenario 2 will give even better return.

scenario 1: Money invested in 401K in XYZ fund, and then taxed when withdrawn (assume no penalty as it's withdrawn after 60). Here we assume that we go in 35% tax bracket in retirement.

money to invest after taxes (tax 0%) money growth in XYZ fund (8%/yr) money after 30 yrs tax on withdrawing (35%) net money after 30 yrs
$10,000 $10,000 $90,000 $100,000 $35,000 $65,000

 scenario 2: Money taken out and invested yourself in XYZ fund. You have to pay taxes before you can invest that money, as there's no deduction. Here we assume that our Long term capital gain tax rate is reduced to 10%.

money to invest after taxes (tax 25%) money growth in XYZ fund (8%/yr) money after 30 yrs tax on withdrawing (10%) net money after 30 yrs
$10,000 $7,500 $67,500 $75,000 $67,500*0.1=$6,750 $68,250

Here, we see that scenario 2 gives us more return. The reason that happens is because the 0% tax rate became an effective long term tax rate of 10% since we moved into higher tax bracket.

Conclusion for 401K:

Let's assume that long term capital gain tax rate will be 15% for people in bottom 99%. It's hard to see how it can go much higher than this, when it's stayed at this level from 2000-2020. Also, maximum tax rate has been < 40% for people in bottom 99%. So, assuming worst case scenario where you move from 25% tax bracket in present to 40% tax bracket in future, and long term capital gain tax rate of 15%, both scenario1 and scenario2 will give you almost the same return. So, the chances are very high that you will end up getting more return by putting that money in some form of retirement account than in your non retirement account. Some may argue that in scenario 2, since you are in higher tax bracket, you will pay higher tax on withdrawal. However remember that all your capital gains are considered long term gains (if you hold your stocks for more than a year) and are taxed at a maximum of 15% (for year 2003-2020). Also all your dividends are considered qualified dividends (if you held the stocks for more than 2 months) and are taxed at a maximum of 15% (for year 2003-2020). The Congress may go back to a maximum of 20% tax rate for long term capital gains and qualified dividends (as has happened since 2019), but it will always be for top 1% of people. Also, you will always have the opportunity to sell them anytime, if they do announce that tax rates are going to go higher. Also you may sell them in a year when you have lower income, so that you will end up paying a much lower tax rate than 15%. People do sell their long term holdings in pieces every year to minimize paying long term capital gains => by spreading out the long term income, you may even pay 0% taxes on these long term profits.

 


 

IRA: After you have exhausted your 401K limits, that is when you should look into contributing to your IRA accounts, assuming you have money left for investment and you are still eligible. Now, which account to invest in: Traditional or ROTH? Let's do some analysis:

Let's take the same example as above.

CASE A: Assume you are in 25% tax bracket now, and in retirement too. There is 15% long term capital gain tax rate in effect.

scenario 1: Money invested in Traditional IRA in XYZ fund, and then taxed when withdrawn (assume no penalty as it's withdrawn after 60)

money to invest after taxes (tax 0%) money growth in XYZ fund (8%/yr) money after 30 yrs tax on withdrawing (25%) net money after 30 yrs
$10,000 $10,000 $90,000 $100,000 $25,000 $75,000

scenario 2: Money invested in Roth IRA in XYZ fund. It's taxed now, but not taxed when withdrawn .

money to invest after taxes (tax 25%) money growth in XYZ fund (8%/yr) money after 30 yrs tax on withdrawing (0%) net money after 30 yrs
$10,000 $7,500 $67,500 $75,000 $0 $75,000

scenario 3: Money taken out and invested yourself in XYZ fund. You have to pay taxes before you can invest that money, as there's no deduction.

money to invest after taxes (tax 25%) money growth in XYZ fund (8%/yr) money after 30 yrs tax on withdrawing (15%) net money after 30 yrs
$10,000 $7,500 $67,500 $75,000 $67,500*0.15=$10,125 $65,000

As you can see in tables above, both scenario 1 and scenario 2 result in exactly the same return. If we believe that we are going to be in higher tax bracket range in old age, then scenario 2 would give better return, while if we believe that we are going to be in lower tax bracket range in old age, then scenario 1 would give better return. Scenario 3 is still worse than other 2 scenarios.

Conclusion for IRA: Let's assume that in 30 years from now, our tax bracket would not go higher than what we are in now. Then both Traditional and Roth give you same return. Personally, I would go with Traditional IRA for following reasons:

  • You save money in taxes now (real savings). These are your prime money making years, so most likely you will will save lot more in taxes now. There may be some extra tax rebates that you may qualify for by reducing your AGI. In retirement, your income may fall off the cliff, and you may move into lower tax bracket anyway.
  • In retirement you decide how much money you want to withdraw from retirement accounts, and hence what tax bracket you want to put yourself in. So, you can control how much tax you want to pay for Traditional IRA/401K withdrawal. We have this option to play in retirement when living off Traditional/401K, so that our taxes are minimized.

If you are really lured towards scenario2, I would ask you to look into scenario 3 => invest the money in non retirement account and pay 15% long term capital gain tax rate on withdrawal. That way you can withdraw the money any time you want, or even better, not withdraw the money at all, and pass it on to your kids, so that they don't become future slaves. That way you pay 0% long term tax rate (There is inheritance tax on passing wealth to kids, but it's applied only when the wealth is above $5M threshold)

 


 

Where should you invest your money?

Investment: Now, comes the fun part of investing your money. Your employer generally offers 10 to 20 different investment options through the trustee, and you can choose a mix of these in the 401K account that you have with the trustee. You can always change the mix of investments, and usually there is no charge for doing that. This can be done online with the account you have with the trustee. Different kind of investment options being offered are:

  • A. Stock mutual funds
  • B. Bond mutual funds
  • C. Stable value accounts
  • D. Money market accounts.

Note that you can't keep cash in 401K account at any time, as any money you put in 401K is supposed to be invested at all the times (or at least that's what my employer's trustee told me, and there's no option for cash parking). Money-market accounts and stable value accounts usually consist of certificates of deposit and U.S. Treasury securities. They are very secure, but offer very small return. From 2009-2022, the returns on these have been close to 0%. The reason is the low interest rate (close to 0% interest rate). Even if these treasuries or CDs offer little return, these funds themselves have a very high expense ratio (usually more than 0.5%), so after deducting this expense, the net return to customer is still 0 (fortunately, these accounts don't give you a negative return yet as of 2022). So, any money you put in these is money lost.

Bond mutual funds are pooled amounts of money invested in bonds. With interest rates going lower and lower every year, you are guaranteed to lose money in bonds. So, you should not invest a dime of your money in bonds.

So, the only option left is "stock mutual funds". Stock mutual funds are portfolios of company stocks. They are considered risky. But they are the least risky of all investments, because they are guaranteed by FED, the government entity that prints money. So, stock market can never lose money, thanks to FED. For stock mutual fund, just invest in something similar to S&P500 index fund, or something with very low expense ratio (0.1% or less). For more information about these, read in our stocks/bonds section. 

 

Is it bad to have too much money in retirement account?

You do not want to end up with too much money in retirement account. Why? Because, there is a clause in IRS that mandates RMD (required Minimum distribution). It forces you to withdraw 4% of your retirement account money every year. So, you end up paying tax on that money. Also, retirement accounts can't be passed on to your kids w/o incurring tax hit (regular income tax rate being applied to all of the money in your retirement account since this tax was never paid in first place). So, no matter how cleverly you plan, you will have to pay 25% or more in taxes on all of your money in your retirement accounts.

Let's say you contribute $20K/year in your 401K plan and $5K/year in your IRA plan. Then you will have contributed about $25K*30=$750K to your retirement accounts in 30 years. Assuming 8% return per year, you will end up with about $4M in your retirement. If your spouse also contributed the same way, then you will have a combined retirement wealth of $8M. You will end up paying about $2M-$3M just in taxes.

Paying so much in taxes is not all gloom and doom. It's a problem I'll love to have !!!

According to an Employee Benefits Research Institute analysis of Federal Reserve data, as of 2024, about 2% of US households have $2M in retirement a/c and 1% have > $3M. This is insane money in retirement a/c and has been made possible entirely due to gangbuster returns of stock market from 2009-2024. You do want to be in the top 1% of the US households by putting in max money in your retirement a/c, all invested in stock Index fund. There's nothing more to do, you will automatically end up in top 1%. Link => https://www.msn.com/en-us/money/retirement/what-percentage-of-retirees-have-2-5-million/ar-AA1BEqQb

 

Final Thoughts:

So, the zist of this article is:

  • you should definitely invest your money in 401K when there's one avilable. Go for maximum limit allowed by IRS.
  • Even after doing this, if you still have money left for investment, open Traditional IRA account and contribute to the maximum amount allowed.
  • If you still have any money left for investment, you should invest in your personal brokerage account (non retirement account).
  • Most important you should never invest a single dime of your retirement money in anything other than stocks/funds. Don't follow the bond/stock mixture crap. Always invest in the market index ETF with lowest expense ratio (such as S&P500, Wilshire5000, etc). See in stock section for more details.

Don't listen to the so called investment experts for your hard earned retirement money. Investment firms are there to maximize their own profits, and governments are there to maximize their taxes. Invest wisely and be on the safe side by participating in government's ponzi scheme of stock market. Good Luck !!

 


 

Python Advanced features: Whatever is mentioned below works for python 3.6 and later (unless mentioned specifically)

Modules:

We saw functions in the previous section. However, since these built in functions are limited, python provides modules which have more functions defined in them. These modules can be imported in other python pgm, so that we don't have to write our own functions for commonly used tasks. There are modules written for almost everything in python, so search python modules before you start writing your function for something complicated. We can create our own modules with our functions in them.

when we want to implement any functionality in module, we can write them as functions. However, if we are working in OOP, we can write them as methods. Most modules provide both function and method support for a given functionality, so you can use any one depending on your preference.

module: are python files (*.py) consisting python code. Any python file can be referenced as module (there's nothing special about a module). Python file called "hello.py" has module name of "hello" that can be imported into other python files. Modules can define functions, classes and variables, and can have any additional code outside of func/classes (i.e calling these functions, running test cases, etc). All of the code within file file1.py is part of the module "file1".

Packages:

We can bundle multiple modules (or multiple files) together to form a package. A package is basically a directory with Python files and a file with the name __init__.py (init with 2 underscore _ on both sides of init). This means that every directory inside of the Python path, which contains a file named __init__.py, will be treated as a package by Python. It's possible to put several modules into a Package. Package is just for convenience where several modules are bundles into one: modules in a package behave exactly like any other module. Package is treated like a higher level module.

ex: we create dir pkg1, and put several files file1.py, file2.py etc in it. Additionally, we need to put init file "__init__.py:, which can be an empty file (but is needed to identify dir pkg1 as a package and not just a dir).  Now the whole dir is treated as package "pkg1". Now we can use dotted module names, i.e A.B is used to refer to module B in package A

Import modules in python:

Once we have downloaded the modules, we can call it in any other python pgm. To do that, first we have to import that module using "import" cmd.

ex: import hello => imports hello module (hello.py has module name of hello, so here hello.py is being included in our current pgm). Any print stmt etc or any function called inside hello.py will be executed, as importing module or file is same as doing an "include file" or putting the code of that imported file in our current file at that location, where import is being called.

ex:
name1.py: python script that contains func "print_def".
main.py: python script thats calls func from name1.py

Import from any dir:

So contents of main.py will look like this:
import name1 => import entire module from name1.py. It first searches for builtin module named "name1", and on not finding a built in module, searches for file named "name1.py" in current dir and then dir specified in "sys.path" var or in environment variable "PYTHONPATH" (from your operating system). By default, "sys.path" includes python system dir only, but we can add user specified dir in it too. If name1 module is in subdir, then we can specify the relative path here as "import subdir1.dir2.name1". We can go up the dir structure by using 1 dot to go one dir above, but it doesn't seem to work for me (i.e import ...dir1/file3 should take you 3 levels higher to dir1, but it gives an error as invalid syntax).

ex: name1.print_def("zara"); => now any func, etc can be called from that module, by specifying name of the module (i.e file), followed by a dot and then the name of func/method/attribute. This is assuming name1 module is in current dir.

ex: subdir1.dir2.name1.print_def("zara"); => This is needed if we imported module from some subdir in current dir (i.e "import subdir1.dir2.name1").

To import modules in any dir (not just subdir starting from current dir), we can't to do in above way. We need to add dir path to sys.path

sys.path.append('/home/user1/dir1/') => Now this dir is added to python sys.path var, so that python will look in this dir also, when searching for modules

sys.path.append('../../dir1/') => Relative paths (relative to current dir where script is running) can also be provided

One very easy way to include modules in any dr is to make soft links to other dir containing these modules in current dir (i.e ln -s ../../dir1 .). Now, all modules are available in subdir of current dir, which can now easily be accessed by doing "import dir1.dir2.name1".

NOTE: many modules are automatically included with python distribution, so you do not need to downlaod them, you call just import them, i,e import math => this imports math module w/o downloading math (as math module is already included with python)

alias: we can also modify the name of module,

ex: import math as m => here math is renamed as "m". So, now we can call math as m. We can also use package.module name i.e import mathplotlib.pyplot as plt. As a convention most modules are imported with a "given" alias name.

print (m.pi); => instead of using math.pi, we used m.pi (as we used alias above)

import specific function: Instead of importing the whole module which imports everything from that module, we can also import specific function from that module:

from random import randint => This is another style of importing func. Here func "randint" is moved from "random" namespace to current namespace, so that dot is no longer required. So, now randint can be called directly, i.e instead of random.randint(), we can call randint(). If we try to call random.randint() now, we'll get an error as "random" namespace is not present anymore. Note: only randint func is imported here (and any other func inside random module is not imported)

from random import * => This imports all functions from module random. Most of the times, we just use * as it's convenient, however if there are too many functions inside that module, then it may affect performance, as a lot of memory will be used up loading unneeded functions.

Import packages in python:

Importing packages is done in same way as importing modules. NOTE: pkg name is no different than dir name, so we can use usual "import from subdir" style that we used for modules above (i.e init files are not needed). Looks like for python3.6 and above, init files are not needed at all, as all ex below work without init file too.

ex: import pkg1 => Here pkg1 is imported, but not the modules inside it. So, if we try to access any module file1 or file2 (i.e pkg1.file1.func1() or pkg1/file2, etc), we'll get an error "name file1 not defined". We have to import modules explicitly.

ex: import pkg1.file1 => Here we import each module explicitly. This is no diff than importing file1.py from dir pkg1 as we saw above for importing modules for subdir. init file is not needed in this case. Here pkg1 namespace is still maintained for these func.  This is helpful in cases where there are functions with same names in different modules

pkg1.file1.func1() => Here full path is needed as file1 is still in namespace "pkg1"

We can also use the "from" style to import modules.Here "from" may have name of module or name of pkg.

ex: from pkg1 import file1, file2 => This is the most common way. This imports both file1.py and file2.py modules from package "pkg1" into current pgm. "from pkg1 import *" doesn't work (errors out), as * is for func/method within modules and not for modules themselves ?? Not sure??

file1.func1() => This function inside file1 module can now be called.

ex: from pkg1.file1 import * => This is valid syntax as we are importing all func from module file1 in pkg1.

 

pip:

To install a module which is not present on your python installation, simply use pip. The most common usage of pip is to install from the Python Package Index using a requirement specifier. Generally speaking, a requirement specifier is composed of a project name followed by an optional version specifier. There are many ways to install various modules in python, but pip is the preferred installer program. Starting with Python 3.4 for Python3 and Python 2.7.9 for Python2, it is included by default with the Python binary installers. So, always use pip to install modules.

To check if pip is installed, run cmd:

pip --version => Since we didn't specify python version here, this cmd runs with python version installed and pointing to python, i.e "python -m pip --version".

pip 18.1 from /usr/lib/python3.4/site-packages/pip (python 3.4) =>  On CentOS, this is the default o/p. This shows that pip is only installed for python3.4, and not for python2 or python3.6. If we run "python -m pip --version" or "python2 -m pip --version", it says "no module named pip" since python2 doesn't have pip installed (since I've python 2.7.5 installed by default). However, "python3.4 -m pip --version", shows pip installed for 3.4. Why "pip --version" shows pip for python3.4 is still puzzling, since this cmd invokes python2, which doesn't have pip installed. My guess is that cmd "pip --version" runs pip with all versions of python, and whichever is the earliest python version it finds pip for, it shows that one.
 
pip 9.0.1 from /usr/lib/python2.7/dist-packages (python 2.7) => On LinuxMint, this is the default o/p. This shows that pip is only installed for python2.7, and not for python3 or python3.6
 
So, above o/p shows that just having pip installed doesn't mean it will work with all python versions. For CentOS 7, pip is installed for python3.4, For Linux Mint, pip is installed for python2, but not for any version of pyhton3. You have to note which python version is pip installed for, and will work with only that python version. So, if we want to install a module for python3.6 using pip, it won't work if pip is not installed for python3.6. We are using python3.6, since it's the latest python version supported on both CentOS and Linux Mint (as of July, 2020).
 
NOTE: pip cmd may point to python2.x or python3.x depending on how it was installed. For that reason, we prefer to use pip3 cmd, which specifically refers o python3.x version
 
CentOS 7:
 
For CentOS 7, pip is installed for python3.4 by default. To install it for python 3.6, run below 2 cmds:
 
$ sudo yum install python3-devel => installs python development libraries (in centOS it's python-devel and NOT python-dev). python-devel is for python2, while python3-devel is for python3. python3 on my machine points to python3.6, it installs things for python3.6. There's no python3.6-devel or python36-devel, you either have it for python or python3. python-dev consists of "Header files, a static library and development tools for building Python modules, This needs to be installed for python3 before we can install pip for python3.
 
$ sudo yum install python3-pip => installs pip for python3. Again, this installs it for python3.6. There's no python3.6-pip or python36-pip.
 
$ python3.6 -m pip --version => just typing "pip --version" will shows pip installed for python3.4 (for reasons mentioned above). "python3 -m pip --version" also gives same below o/p as python3 points to python3.6.
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6) => This shows that pip got installed correctly for python3.6. Above in cmd "pip --version", this was pointing to python3.4
 
Linux Mint:
 
Since python3.6 is the only python3 installed, following cmds install pip for python3. FIXME: Looks like pip gets installed for all versions of python3? or only for version that python3 is pointing to?? FIXME
 
sudo apt install python3-distutils => this needed else we get couple of syntax errors when running next cmd

sudo apt install python3-pip => This installs pip for python3. if we use "sudo apt install python-pip", then it installs pip for python2.

python3 -m pip => Now running this cmd will either show options which means pip is installed correctly for python3, or it will say "module pip not found" which means pip didn't get installed correctly for python3. Or we can also type "python3 -m pip --version" to see version number of pip.

Install modules using pip:

Once pip is installed, we can use it to install other Python modules. cmds are same on both CentOS and LinuxMint.

ex: python3.6 -m pip install SomePackage => This installs package named "SomePackage". Here, instead of running pip directly, we prepend it with "python3.6 -m pip". This runs appropriate copy of pip for python3.6. This is helpful when there are multiple python versions installed on your system. Here pip is called for python3.6, so that SomePackage is installed for python3.6. This is preferred way, since there is no ambiguity on which version of python was this package installed for.

If module gets installed for python3, we see all those modules in this dir: /usr/local/lib64/python3.6/site-packages/*

However, if it's gets installed for python2, we see those modules here: /usr/lib64/python2.7/site-packages/*

We can use unix "locate" cmd to find out where these libs are. i.e locate python2 => shows all libs and other dir for python2.

Below are some very helpful modules that you should install as they may be required for many projects.

1.pygame: pygame is very popular gui package for python for building games. See on pygame.org for more details. It's very easy for kids to get started on this and build sleek games. To install pygame module on python3, run this:

$ pip install pygame => This installs pygame module on your system, so that it can be imported in any python file. However, here since we didn't provide specific python version, it uses copy of pip for python. This is equiv to "python -m pip install pygame". However, python here may be pointing to python2, python3 or python3.6, This may install pygame only for python version pointed to (if python points to python2, then pygame is only installed for python2. If we import pygame in python3 pgm, it will error out saying module not found), so better to specify python version

$ sudo python3 -m pip install -U pygame => this install pygame for python3. -U option updates pygame module if already installed. Here pygame package is installed for python3 (or python3.6 as python3 is pointing to python3.6). Or, we can run this cmd "python3 .6-m pip install pygame", it's the same thing. 

 

Important modules: Below are few modules that are already included with distribution, and are useful for carrying out many tasks.

Module random: It generates random numbers

import random => importing built in module named random. All methods or functions in random module are imported here

print (random.randint(1,30)) => calls func returning random int b/w range 1 to 30. Functions within modules are called by separating them via dot (to indicate that the function is in the namespace "random".

from random import randint => If we import randint function this way, then we just do print (randint(1,30)).

Module os: One  of the important modules is "os" module. It provides operating system i/f. exec* functions loads new pgm with optional args.

from os import execvp, envron => imports these 2 methods from os module. execvp loads new pgm, while environ function provides shells environment var.

exexvp(file, args) => this executes a new pgm specified by "file" (with args as specified), replacing the current process, they do not return. The new executable is loaded into current process.

environ['HOME'] => This provides the value of HOME environment var found in bash, csh, etc.

ex: os.rmdir(/home/scratch) => runs unix cmd rmdir, so causes /home/scratch dir to be removed

Module sys: This module provides  "argv" func to get access to cmd line args. sys.argv is list of cmd line args. We can also access individual args as sys.argv[0], sys.argv[1] etc

ex: file fil1.py

from sys import argv # or just "import sys"

print ("Args are", argv[0], argv[1], ...)

run file1.py abc 179 my_name => here argv[0]= file.py, argv[1]=abc, ...

Standard library: python's std lib contains many built in modules (written in C) that provides access to system functionality such as file I/O (which would otherwise be inaccessible to python programmers) as well as many python modules for a variety of simple/complicated tasks. This std lib contains data types, built in functions (so that no import is needed), and tons of modules. This std lib is included in any python pgm by default.

A. Date and Time:
import time;
ticks = time.time() => ticks is floating point num. 1st time is time module, while 2nd time is time method working on time module
print "Ticks=",ticks => prints ticks since Jan 1, 1970
localtime = time.localtime(time.time()) => gets local time

import calendar
cal = calendar.month(2008, 1) => gets calender for Jan 2008. Here calender is module and month is the method

regular expression:  helps match or find patterns using special syntax. This is very useful feature as most of the times scripts are used for matching, replacing, etc words in documents. module re along with it's many functions used for this.

1. module re: module re provides full support for Perl-like regular expressions in Python. The re module raises the exception re.error if an error occurs while compiling or using a regular expression.

match func:
re.match => re.match function returns a match object on success, None on failure.
We use group(num) (returns entire match or specific match num if specified) or groups() (returns all matching subgroups in tuple) function of match object to get matched expression.
syntax: re.match(pattern, string, flags=0)
Since various characters have special meaning when they are used in regular expression, to avoid any confusion while dealing with regular expressions, we would use Raw Strings as r'expression'.
control char: decides how to match
. => Matches any single character except newline. Using m option allows it to match newline as well.
[...] => Matches any single character in brackets. [abc] matches any of a or b or c
[^...] => Matches any single character not in brackets. ex: [^0-9] => match anything other than digit
re* => Matches 0 or more occurrences of preceding expression.
re+ => Matches 1 or more occurrence of preceding expression.
re? => Matches 0 or 1 occurrence of preceding expression.
a|b => Matches either a or b.
(re) => Groups regular expressions and remembers matched text. (.*) me => matches 0 or more char until "space me" matches
\d+ => match any num of digits \D => match any nondigit, \d{3,5} => match 3,4 or 5 digits
\s => match whitespace, \S => match non whitespace
\w => match single word char

ex:
<.*> => matches in greedy way. So will match full <python>perl> in <python>perl>
<.*?> => matches in non greedy way (since ? means 0 or 1 occurrence only). So will match <python> in <python>perl>
\bpyth(on|off)\b => match puthon or pythoff
ex:
import re => import re module
line = "Cats are smarter than dogs"
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I) => (.*) matches char in greedy fashion (matches smallest possible), while (.*?) matches char in non-greedy fashion, and stored in group. re.M, re.I are optional flags. re.I performs case insensitive matching, while re.M makes $ match the end of a line (not just the end of the string) and makes ^ match the start of any line (not just the start of the string). multiple flas are provided by using exclusive OR (|)
if matchObj: => match obj returned on match, else None returned
   print "matchObj.group() : ", matchObj.group() => returns entire match since no num specified => Cats are smarter than dogs
   print "matchObj.group(1) : ", matchObj.group(1) => returns 1st match within () => Cats
   print "matchObj.group(2) : ", matchObj.group(2) => returns 2nd match within () => smarter. using (.*) will match in non greedy fashion, so it will match as much as possible until it finds spce and few char after it. so (.*) will match "smartar than" as there space after "than".
else:
   print "No match!!"

search func: similar to match in perl, where it looks for match anywhere in string (as opposed to match which looks for match only in beginning of string)
ex:
matchObj = re.match( r'dogs', line, re.M|re.I) => returns None since dogs is not at beginning of line
searchObj = re.search( r'dogs', line, re.M|re.I) => returns dogs since it appears somewhere in line

search and replace func:

ex:
phone = "2004-959-559 # This is Phone Number"
num = re.sub(r'#.*$', "", phone) => substitute anything after # until end of string with blank, so num = 2004-959-559
num = re.sub(r'\D', "", phone) => substitute any non digit with blank, so num =  2004959559. we don't need \D+ as sub does global replacement on that string for every occurnce of that pattern.

CGI, database access, webpage, sending email all can be achieved via python by importing particular modules

 

Static Timing Analysis (STA) Flow:

Once we have converted RTL to netlist, it's time to run Timing analysis on gate level netlist. When we have RTL, there is no concept of gates or delay. RTL is modeled as zero delay, so there is no delay, and as such no setup or hold times to meet. However, once this RTL is converted to gates, we have real delays for these gates. In order for this netlist to behave the same as RTL, all paths need to meet timing.

Static Timing Analysis commonly known as STA is the flow where we run a timing tool that analyzes all paths and finds out f there is any setup/hold violation on any of these paths.

Tools:

There are STA software available from both cadence and synopsys as well in open source world. PrimeTime (PT) from Synopsys is considered the gold standard for STA. Cadence has it's own tool called Encounter Timing System aka ETS. These are the 2 timing tools that are used by almost all the companies to run STA. From open source side, we have Vesta written by Tim Edwards. There is also another open source STA called OpenTimer. We'll discuss about each of these tools separately in their own sections.

STA timing corners:

STA requires running design at various corners. Recall that a tarnsistor's delay depends on PVT (see in solid state devices section for more details).

We run timing on max, min and typ corners. We run both "setup" and "hold" runs across all 3 corners (typ corner is optional, and many times just running max and min corner suffices)

 

 

 

 

Raspberry 4:

This is the latest and most powerful raspberry pi, released in 2019. It's also known as Raspberry Pi 4B (there is no Raspberry Pi 4A). There are three current Raspberry Pi 4 models that are identical, except for the amount of RAM. Cheapest one at 2GB ram, next one at 4GB ram, and highest performing one at 8GB. Even the 2GB one is powerful enough to work as a desktop. 4GB version suffices for almost any application, as Raspbian OS is very memory efficient, and never exceeds 4GB even with bunch of tabs and processes running. It is powered by a new processor, the Broadcom BCM2711B0, which is built in 28nm, and is based on ARM Cortex-A72 core, instead of earlier ARM Cortex A53 core. it has 4 CPU and clock speed of 1.5GHz. It also has a GPU from Broadcom called VideoCore VI, running at 500MHz.

Installation:

To use Raspberry pi, you will need to raspbian as explained in previous "Raspberry" section. Then you install vncserveer for raspbian, so that you can work on the raspberry w/o having a monitor and keyboard. Once vncserver is running, you access raspberry pi using vncviewer from some other laptop. Now you can start working on this great little machine.

Getting started:

Open a terminal, and type "pinout" cmd. This gives info on all the pins on the header that can be used for our purpose.

Setup time  and Hold time:

Any logic you design from RTL, you will always hear about setup time and hold time, when running timing tools. Sequential elements such as flops and latches have setup and hold time requirements, in order to function correctly.Let's explore this important concept.

Origin of setup and hold time:

In broader terms, any circuit that stores value has a back to back inverter or some other back to back gates to hold the value. However such a circuit is not of much use, unless we can control the value that's stored in this back to back inverter. This is done via a signal to enable or disable the write, and another signal which transmits the value to be written into. This signal which enables or disables the write has a timing relation wrt to the signal that we are trying to write in. The value to be written in has to be stable around the time, the enable/disable signal changes, or else we may not store the desired value. This time window where we want our input signal to be stable is called setup time and hold time.

Setup time: The time before the enable signal that the input signal has to be stable

Hold time: The time after the enable signal that the input signal has to be stable

 The sum of "setup_time + hold_time" is the window where the input signal shouldn't change, or else the value stored in the seq element would be unpredictable.

This link does a superb job of explaining them:

https://www.edn.com/understanding-the-basics-of-setup-and-hold-time/

Setup and hold time in circuit paths:

We understand the setup/hold time of flops/latches, etc. But let's say we have a path from 1 flop to other flop. The 2nd flop can't have it's data change within it's setup/hold window.

Let's see a simple 2 bit counter. Violating setup time (too slow) or hold time (too fast) causes counter to have incorrect values as shown in the diagram.

Attach diagram FIXME

Eqn is:

That's why the 0 cycle path is called the hold timing for the path, as "hold time" of the capturing flop is involved in the eqn. Being a 0 cycle path, the freq of the clk has no impact on whether the path meets the "hold time". So, these paths are independent of freq.

Similarly 1 cycle path is called the setup timing for the path, as "setup time" of the capturing flop is involved in the eqn. Being a 1 cycle path, the freq of the clk will impact on whether the path meets the "setup time". So, these paths are dependent on freq, and setup time of the path can be fixed by relaxing the clk freq.

 

Timing Tools applying setup and hold time:

In PT and other timing tools, single cycle paths are easy to analyze. Usually paths are from flop to flop. So, most of the designs have 0 cycle hold paths and 1 cycle setup paths. When we have multiple clks with diff freq, then relationship gets more complex. Discuss MCP, and how setup/hold are calculated by timing tools