0% found this document useful (0 votes)
24 views21 pages

Week 1

ucl math

Uploaded by

ran ju
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views21 pages

Week 1

ucl math

Uploaded by

ran ju
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

MATH0011 Python L1

Re-attempting assessed exercises


If you didn't get full marks, you can re-attempt once.
You must do this by 10am the Monday after the original deadline.
Modify the original file you submitted Assessed Exercises/Week 1/Week
1 assessed exercise.ipynb
Lists
Python lists let us store sequences of objects in lists.

In [ ]: l = [1, "two", 3] # list creation


l.append(4) # now l is [1, "two", 3, 4]
l = l + [5, 6] # + is concatenation
l[0] # access the 0th list element
A new kind of assignment
Previously we've used <name> = <expression> assignments (simple
assignments)
We can modify list entries in a similar way

In [ ]: l = [1, 2, 3]
l[0] = 99 # New type of assignment: not just a name on the left
print(l)
Mutable and immutable types
Some Python types, like lists, can be modified after creation. Others cannot.

In [ ]: s = "hello"
s[0] = "H" # ERROR - strings are immutable
u = (1, 2, 3) # u is a "tuple"
u[0] = 99 # ERROR - tuples are immutable

Strings and tuples are immutable, lists are mutable.


Frame diagrams for lists
a = [1, 2, 3]
Mutability and immutability examples
In [ ]: a = 1
b = a
b = 2
print(a) # ??

In [ ]: s = [1, 2, 3]
t = s
t[0] = 99
print(s) # ??

Names s and t point to the same structure in memory, so mutations to t are visible in
s.
What really happens in a function call
Suppose you have a function f with one formal parameter x , and that a is a variable.
When f(a) is called

a new local frame for f is created...


...with x referring to the same thing in memory that a does.
Functions with mutable and immutable
arguments
In [ ]: a = 1
def f(x):
x = 10
f(a)
print(a) # what will it print?

In [ ]: a = [1, 2, 3]
def f(x):
x[0] = 99
f(a)
print(a) # what will it print?
Example/Recap
In [ ]: a = [1, 2, 3]
def g(x):
x = [99, 99, 99]
g(a)
print(a) # what will it print?

Simple <name> = <expression> assignments inside functions always create


new local variables
List assignments like l[1] = 2 never create new variables - they modify the
value of l .
Always be careful when creating mutable variables and passing them to functions.
Example: prepend
l.append(x) returns nothing - it modifies the list l by adding x to the end.
Let's write a function prepend(x, l) that returns nothing, but modifies the list
l by adding x to the front.

In [2]: def prepend(x, l):

[1, 2]
List and string slicing
l[a : b] is the list [l[a], l[a+1], ..., l[b-1]] .
This is called a slice of l .
You can use the same syntax to slice strings, too.

In [ ]: a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']


a[1 : 5]
Problem
Find the largest sum of 10 consecutive digits in the number
58353189537985371583910573819053785743856726735497410003473493615345389472
47839473289513896189546384371849178491654910547563708546378043678290638956
56738291564387526348247385932658934253429156295682356816375635634953273815
05982365637248237157360851673495267832107538951638295647564782562749562839
06238951689316589321562189305682356732819573285071235632789573289056321856
73827483748374106116543016410645395673480573885743857385903718537583758175
...
Solution
Split the problem into parts, solve and test each part separately.

In [ ]: def string_sum(s):
# return the sum of the digits in a string consisting of digits
total = 0
for digit in s:
total = total + int(digit)
return total

In [ ]: string_sum("1234")
In [ ]: def maximum_slice_sum(s, k):
# return the maximum sum of k consecutive digits in s, where k <= l

Try test cases where you know the answer, and special cases that might reveal errors.

In [ ]: maximum_slice_sum("991299993456", 3)

In [ ]: s = "583531895379853715839105738190537857438567267354974100034734936153
maximum_slice_sum(s, 10)
Classes
Classes let us create our own Python data types

to work with complex data more easily,


so that we can adapt operators like + or == or > to new types.

Let's create a class representing a UCL student. Each instance of the UCLStudent
class will have a name and a degree subject. These are called instance variables.

In [ ]: class UCLStudent:
def __init__(self, name, subject):
self.student_name = name # create an instance variable student_
self.degree_subject = subject
Working with our class
In [ ]: class UCLStudent:
def __init__(self, name, subject):
self.student_name = name # create an instance variable student_
self.degree_subject = subject

To create a new instance of this class and access its instance variables:

In [ ]: a = UCLStudent("Zeta", "Mathematics")

In [ ]: print(a.student_name, a.degree_subject)
Class methods
We can write functions inside a class definition for working with objects of that class.
These are called class methods.

In [ ]: class UCLStudent:
...
def speak(self): # a class method
# self refers to the instance of the class on which this method
print("my name is " + self.student_name + " and I study " + sel

To use this class method:

In [ ]: a = UCLStudent("Zeta", "Mathematics")
a.speak() # think of this as being like speak(a)
Overriding built-in operators
We can tell Python how to use + , - , * , == , > , < , str ... on our classes by
implementing special class methods.

In [ ]: a = UCLStudent("Zeta", "Mathematics")
b = UCLStudent("Zeta", "Mathematics")
a == b

To tell Python how to use == on UCLStudent objects, write an __eq__ method:

In [ ]: class UCLStudent:
...
def __eq__(self, other):
# return True if self should be regarded as equal, otherwise Fa
return (self.student_name == other.student_name) and (self.degr

a == b will now work as expected on UCLStudent objects.


A vector class
Let's define a class to represent column vectors of height 2.

In [ ]: class Vector:
def __init__(self, x, y):
self.x = x
self.y = y

To add Vector s using + , implement __add__(self, other)

In [ ]: class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)

In [ ]: a = Vector(1, 1)
b = Vector(2, -1)
c = a + b
print(c.x, c.y)

You might also like