<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Data aliasing
One of the trickiest things about programming is figuring out exactly what data a variable refers to. Remember that we use names like data and salary to represent memory cells holding data values. The names are easier to remember than the physical memory addresses, but we can get fooled. For example, it's obvious that two variables x and y can both have the same integer value 7
Step1:  But, did you know that they are both referring to the same 7 object? In other words, variables in Python are always references or pointers to data so the variables are not technically holding the value.  Pointers are like phone numbers that "point at" phones but pointers themselves are not the phone itself.
We can uncover this secret level of indirection using the built-in id(x) function that returns the physical memory address pointed out by x. To demonstrate that, let's ask what x and y point at
Step2:  Wow! They are the same.  That number represents the memory location where Python has stored the shared 7 object.
Of course, as programmers we don't think of these atomic elements as referring to the same object; just keep in mind that they do. We are more likely to view them as copies of the same number, as lolviz shows visually
Step3:  Let's verify that the same thing happens for strings
Step4:  Ok, great, so we are in fact sharing the same memory address to hold the string 'parrt' and both of the variable names point at that same shared space. We call this aliasing, in the language implementation business.
Things only get freaky when we start changing shared data. This can't happen with integers and strings because they are immutable (can't be changed). Let's look at two identical copies of a single list
Step5:  Those lists have the same value but live a different memory addresses. They are not aliased; they are not shared. Consequently, changing one does not change the other
Step6:  On the other hand, let's see what happens if we make you and me share the same copy of the list (point at the same memory location)
Step7:  Now, changing one appears to change the other, but in fact both simply refer to the same location in memory
Step8:  Don't confuse changing the pointer to the list with changing the list elements
Step9:  This aliasing of data happens a great deal when we pass lists or other data structures to functions. Passing list Quantity to a function whose argument is called data means that the two are aliased. We'll look at this in more detail in the "Visibility of symbols" section of Organizing your code with functions.
Shallow copies
<ASSISTANT_TASK:>
Python Code:
x = y = 7
print(x,y)
Explanation: Data aliasing
One of the trickiest things about programming is figuring out exactly what data a variable refers to. Remember that we use names like data and salary to represent memory cells holding data values. The names are easier to remember than the physical memory addresses, but we can get fooled. For example, it's obvious that two variables x and y can both have the same integer value 7:
End of explanation
x = y = 7
print(id(x))
print(id(y))
Explanation: But, did you know that they are both referring to the same 7 object? In other words, variables in Python are always references or pointers to data so the variables are not technically holding the value.  Pointers are like phone numbers that "point at" phones but pointers themselves are not the phone itself.
We can uncover this secret level of indirection using the built-in id(x) function that returns the physical memory address pointed out by x. To demonstrate that, let's ask what x and y point at:
End of explanation
from lolviz import *
callviz(varnames=['x','y'])
Explanation: Wow! They are the same.  That number represents the memory location where Python has stored the shared 7 object.
Of course, as programmers we don't think of these atomic elements as referring to the same object; just keep in mind that they do. We are more likely to view them as copies of the same number, as lolviz shows visually:
End of explanation
name = 'parrt'
userid = name # userid now points at the same memory as name
print(id(name))
print(id(userid))
Explanation: Let's verify that the same thing happens for strings:
End of explanation
you = [1,3,5]
me  = [1,3,5]
print(id(you))
print(id(me))
callviz(varnames=['you','me'])
Explanation: Ok, great, so we are in fact sharing the same memory address to hold the string 'parrt' and both of the variable names point at that same shared space. We call this aliasing, in the language implementation business.
Things only get freaky when we start changing shared data. This can't happen with integers and strings because they are immutable (can't be changed). Let's look at two identical copies of a single list:
End of explanation
you = [1,3,5]
me  = [1,3,5]
print(you, me)
you[0] = 99
print(you, me)
Explanation: Those lists have the same value but live a different memory addresses. They are not aliased; they are not shared. Consequently, changing one does not change the other:
End of explanation
you = [1,3,5]
me  = you
print(id(you))
print(id(me))
print(you, me)
callviz(varnames=['you','me'])
Explanation: On the other hand, let's see what happens if we make you and me share the same copy of the list (point at the same memory location):
End of explanation
you[0] = 99
print(you, me)
callviz(varnames=['you','me'])
Explanation: Now, changing one appears to change the other, but in fact both simply refer to the same location in memory:
End of explanation
you = [1,3,5]
me  = you
callviz(varnames=['you','me'])
me = [9,7,5] # doesn't affect `you` at all
print(you)
print(me)
callviz(varnames=['you','me'])
Explanation: Don't confuse changing the pointer to the list with changing the list elements:
End of explanation
X = [[1,2],[3,4]]
Y = X.copy() # shallow copy
callviz(varnames=['X','Y'])
X[0][1] = 99
callviz(varnames=['X','Y'])
print(Y)
Explanation: This aliasing of data happens a great deal when we pass lists or other data structures to functions. Passing list Quantity to a function whose argument is called data means that the two are aliased. We'll look at this in more detail in the "Visibility of symbols" section of Organizing your code with functions.
Shallow copies
End of explanation
<END_TASK>