The concepts of call-by-value vs call-by-reference are simple and easy to distinguish once somebody has understood this basic concept in languages. I don't mean to disregard newcomers, though. And in-fact I think that it is doing a disservice to them to make python sound like it is radically different and more complicated than other languages. Instead I think a newcomer is best served by helping them grasp basic, common language concepts as they apply to python as well as other languages.
I really also need call out that there seem to be a lot of inaccuracies with regards to other languages than python on this thread and even some confusing terminology and analogies by the article's author. Specifically there seem to be a lot of misunderstandings about C (and even C++) flying around and being perpetuated here.
For example, you compared passing a python object to passing a struct in C. Passing a C struct to a function does _not_ copy all the fields of the struct. It passes a reference (pointer) to the function, which the function then uses to access the fields (or properties if you will) in the struct directly at their original location in memory.
You do get automatic copies of primitive numeric types when you pass them to functions in C. The reasoning and distinction is pretty simple: they fit in hardware registers.
But, a struct, an array, or a string (or character array) is always going to be passed as a pointer. When you pass it to a function, the only way you get a copy of it is if you explicitly copy the value to a new location in memory and point to it. You can of-course also pass a pointer to a numeric value to a function as well (as in func(int *var)) instead of the actual value (as in func(int var)), in which case the same semantics apply.