June+22nd+2016+by+Tom

=Agenda for June 22,2016:=

-- Get the solution of the 8 following questions in class time:
Hint: Python list operation: l String to list l List to string l List how to iterate

Reference [] [] []

1. Define a function sum and a function multiply that sums and multiplies (respectively) all the numbers in a list of numbers. For example, sum([1, 2, 3, 4]) should return 10, and multiply([1, 2, 3, 4]) should return 24.

2. Define a function reverse that computes the reversal of a string. For example, reverse("I am testing") should return the string "gnitset ma I".

3. Define a function is_palindrome that recognizes palindromes (i.e. words that look the same written backwards). For example, is_palindrome("radar") should return True.

4. Write a function is_member that takes a value (i.e. a number, string, etc) x and a list of values a, and returns True if x is a member of a, False otherwise. (Note that this is exactly what the in operator does, but for the sake of the exercise you should pretend Python did not have this operator.)

5. Define a function overlapping that takes two lists and returns True if they have at least one member in common, False otherwise. You may use your is_member function, or the in operator, but for the sake of the exercise, you should (also) write it using two nested for-loops.

6. Define a function generate_n_chars that takes an integer n and a character c and returns a string, n characters long, consisting only of c:s. For example, generate_n_chars(5,"x") should return the string "xxxxx". (Python is unusual in that you can actually write an expression 5 * "x" that will evaluate to "xxxxx". For the sake of the exercise you should ignore that the problem can be solved in this manner.)

7. Define a procedure histogram that takes a list of integers and prints a histogram to the screen. For example,histogram([4, 9, 7]) should print the following:

8. Plot a pie graph for a list of numerical inputs, better with fill colors and labels.

Sample codes and optimized version(programmed by Tom Zhou and optimized by Mrs. Wudi):
If you have seen these codes and optimized versions, you will probably find that there is no difference between their functionality. However, optimizations do somehow make the codes more understandable and intuitive, or improve the algorithm and thus reduce the workload of computer.**

Q1:
code format="python" def Sum(a): summ = 0 for i in range(0,len(a)): summ += a[i] return summ def multiply(a): resultt = 1 for i in range(0, len(a)): resultt = resultt * a[i] return resultt a = [1,2,3,4] print (Sum(a),multiply(a)) code

Optimization:
code format="python" def Sum(a): summ = 0 for i in a:  # for i in a:        summ += i            #   summ += i    return summ def multiply(a): resultt = 1 for i in a:  # the same as above resultt = resultt * i   return resultt
 * <>: to be replaced by specific variables
 * 1) for in :
 * 2) for each loop  is going to take one element from in the order of left to right.
 * Q1: Opt Version

a = [1,2,3,4] print (Sum(a),multiply(a)) code

Q2:
code format="python" def reverse(a): a = a[::-1] return a a = "Roll out!" print(reverse(a)) code

Optimization:
code format="python" def reverse(a): b = '' for i in a:       b = i + b    return b InputStr = "Roll out!" print(reverse(InputStr)) code
 * 1) using a[:,:,-1] is almost no difference to a.reverse....
 * 2) sample code below:
 * 3) Q2 : opt Version

Q3:
code format="python" def is_palindrome(a): if a[::-1] == a:       return True else: return False print(is_palindrome("dad")) code

Optimization:
code format="python" def is_palindrome(a): if a == reverse(a): return True else: return False print(is_palindrome("dad")) code
 * 1) Well, you can use the function you've defined above....
 * 2) Q3 : opt Version

Q4:
code format="python" def is_member(a,list): for i in range(0,len(list)): if list[i] == a:           tf = True break else: tf = False return tf list = [1,2,3,4,5] a = 4 print (is_member(a,list) ) code

Optimization:
code format="python" def is_member(x,a): flag = False for i in a:       if x == i:            flag = True return flag
 * 1) again: to visit every element of the list, no need to use index
 * 2) also you can use a boolean flag variable for return
 * 3) Also list is not suitable for a variable name!
 * 4) Q4 : opt Version

a = [1,2,3,4,5] x = 4 print (is_member(x,a) ) code

Q5:
code format="python" def overlapping(list1,list2): for i1 in range(0,len(list1)): for i2 in range(0, len(list2)): if list1[i1] == list2[i2]: tf = True break else: tf = False if tf == True: break return tf list1 = [5,6,7,8,9] list2 = [3,4,5,1,2] print (overlapping(list1,list2)) code

Optimization:
code format="python" def is_member(x,a): flag = False for i in a:       if x == i:            flag = True return flag def overlapping(list1,list2): flag = False for i1 in list1: if is_member(i1,list2): flag = True return flag list1 = [5,6,7,8,9] list2 = [3,4,5,1,2] print (overlapping(list1,list2)) code
 * 1) guys, you can make full use of your own code!
 * 2) Q5 -- Opt Version

Q6:
code format="python" def generate_n_chars(number,char): chars = char for i in range (0,number-1): chars += char return chars number = 99 char = "6" print(generate_n_chars(number,char)) code

Optimization:
code format="python" def generate_n_chars(number,char): chars = '' for i in range (number): chars += char return chars number = 99 char = "6" print(generate_n_chars(number,char)) code
 * 1) The following is a bit more intuitive?
 * 2) Q6 Opt Version

Q7:
code format="python" def histogram(list): for x in range(0,len(list)): bar = "" for y in range(0,list[x]): bar += "*" print(bar) list = [5,7,2,4] histogram(list) code

Optimization:
code format="python" def generate_n_chars(number,char): chars = char for i in range (0,number-1): chars += char return chars
 * 1) again, same list iteration problem
 * 2) use your own defined function
 * 3) reasonable variable name
 * 4) Q7 -- Opt Version

def histogram(lista,symbol): for x in lista: print(generate_n_chars(x,symbol))

Input_list = [5,7,2,4] histogram(Input_list,'@') code

<span style="color: #333333; font-family: arial,helvetica,sans-serif;">Q8:
code format="python" import turtle import random Window = turtle.Screen Tom = turtle.Turtle Tom.hideturtle Window.colormode(255) Tom.speed(0) def piegraph(list,radius,label): Tom.left(90) for i in range(0,len(list)): Tom.fillcolor(int(random.uniform(0,255)),int(random.uniform(0,255)),int(random.uniform(0,255))) Tom.begin_fill Tom.forward(radius) Tom.right(90) Tom.circle(-radius,180 * (list[i]/sum(list))) xcor = Tom.xcor ycor = Tom.ycor Tom.left(90) angle = Tom.heading Tom.right(90) Tom.circle(-radius, 180 * (list[i] / sum(list))) Tom.right(90) Tom.forward(radius) Tom.end_fill Tom.left(180) xcor1 = Tom.xcor ycor1 = Tom.ycor Tom.penup Tom.goto(xcor,ycor) Tom.pendown oldangle = Tom.heading if angle <= 90 or angle >=270: Tom.setheading(angle) Tom.forward(40) Tom.penup Tom.forward(20) Tom.write(label[i] + " " + str(round(list[i] / sum(list) * 100,1)) + "%",False,align = "left",font = ("Calibri",14,"bold")) Tom.goto(xcor1,ycor1) Tom.setheading(oldangle) Tom.pendown else: Tom.setheading(angle) Tom.forward(40) Tom.penup Tom.forward(10) Tom.write(label[i] + " " + str(round(list[i] / sum(list) * 100,1)) + "%", False, align="right", font=("Calibri", 14, "bold")) Tom.goto(xcor1, ycor1) Tom.setheading(oldangle) Tom.pendown list = [] label = [] radius = 0 while 1: appendix = input("Please enter your data, one at a time. Type 'stop' to stop.") if appendix == "stop": break list.append(int(appendix)) while 1: appendix = input("Please enter your label corresponding to your data, one at a time. Type 'stop' to stop.") if appendix == "stop": break label.append(appendix) radius = int(input("Please enter the radius of the pie.")) piegraph(list,radius,label) Window.mainloop code ===<span style="color: #ff0000; font-family: arial,helvetica,sans-serif;">Because I like to draw short lines pointing outward to label each segment and have a separated list of labels, so I optimized my own code. In addition, my version has the instructions for user interactions. Mrs. Wudi's optimized and more concise version was shown at the bottom. ===

<span style="color: #ff0000; font-family: arial,helvetica,sans-serif;">Optimization by Tom:
code format="python" import turtle import random Window = turtle.Screen Tom = turtle.Turtle Tom.hideturtle Window.colormode(255) Tom.speed(0) def piegraph(list1, radius, label): Tom.left(90) # pre-calculation of sum can avoid repetitive calculation inside the loop. list_sum = sum(list1) # because there're two bijective lists, one index can acquire members of both lists correctly. for i in range(0, len(list1)): Tom.fillcolor(int(random.uniform(0, 255)), int(random.uniform(0, 255)), int(random.uniform(0, 255))) Tom.begin_fill Tom.forward(radius) Tom.right(90) Tom.circle(-radius, 180 * (list1[i]/list_sum)) # draw a line outside and perpendicular to the arc Tom.left(90) Tom.forward(40) Tom.penup Tom.forward(20) # adjust the position of text if 90 <= Tom.heading <= 270: ali = "right" else: ali = "left" Tom.write(label[i] + ": " + str(round(list1[i] / list_sum * 100, 2)) + "%", False, align=ali, font=("Calibri", 14, "bold")) # go back to original position and continue drawing other half of the arc Tom.backward(60) Tom.right(90) Tom.pendown Tom.circle(-radius, 180 * (list1[i] / list_sum)) Tom.right(90) Tom.forward(radius) Tom.end_fill Tom.left(180) list1 = [] label = [] while 1: appendix = input("Please enter your data, one at a time. Type 'stop' to stop.") if appendix == "stop": break list1.append(int(appendix)) list1.sort(reverse=True) while 1: appendix = input("Please enter your labels corresponding to your data, one at a time. Type 'stop' to stop.") if appendix == "stop": break label.append(appendix) radius = int(input("Please enter the radius of the pie.")) piegraph(list1, radius, label) Window.mainloop code

<span style="color: #ff0000; font-family: arial,helvetica,sans-serif;">Optimization by Mrs. Wudi:
code format="python" import turtle import random Window = turtle.Screen Tom = turtle.Turtle Tom.hideturtle Window.colormode(255) ### Use the R,G,B color ocmponent color mode is very good. Tom.speed(10)
 * 1) A more concise version which combines the implementation of Doris' and Tom's
 * 2) Q8 -- Opt Version

def pie_chart(list1,radius): list_sum = sum(list1) for i0 in list1: i = round(i0 / list_sum,2) Tom.fillcolor(int(random.uniform(0,255)),int(random.uniform(0,255)),int(random.uniform(0,255))) Tom.begin_fill Tom.forward(radius) Tom.left(90) Tom.circle(radius,360*i) Tom.right(90) Tom.goto(0,0) Tom.end_fill

### write labels Tom.penup Tom.right(180*i) Tom.forward(radius + 30) labelText = str(i0) + ": " + str(i) Tom.write(labelText, True, align="center", font=("Calibri", 12, "bold")) Tom.goto(0,0) Tom.left(180*i) Tom.pendown

Window.mainloop

pie_chart([30,20,40,50,15],200) code