课程页面:https://www.udacity.com/course/intro-to-computer-science--cs101
授课教师:Dave Evans https://www.cs.virginia.edu/~evans/
如下内容包含课程笔记和自己的扩展折腾
课堂笔记
find_second
# Define a procedure, find_second, that takes
# two strings as its inputs: a search string
# and a target string. It should return a
# number that is the position of the second
# occurrence of the target string in the
# search string.
def find_second(a, b):
first = a.find(b)
second = a.find(b, first+1)
return second
danton = "De l'audace, encore de l'audace, toujours de l'audace"
print find_second(danton, 'audace')
#>>> 25
twister = "she sells seashells by the seashore"
print find_second(twister,'she')
#>>> 13
is_friend
# Define a procedure, is_friend, that takes
# a string as its input, and returns a
# Boolean indicating if the input string
# is the name of a friend. Assume
# I am friends with everyone whose name
# starts with either 'D' or 'N', but no one
# else. You do not need to check for
# lower case 'd' or 'n'
def is_friend(name):
return name[0] == "D" or name[0] == "N"
#print is_friend('Diane')
#>>> True
#print is_friend('Ned')
#>>> True
#print is_friend('Moe')
#>>> False
get_next_target
# Modify the get_next_target procedure so that
# if there is a link it behaves as before, but
# if there is no link tag in the input string,
# it returns None, 0.
# Note that None is not a string and so should
# not be enclosed in quotes.
# Also note that your answer will appear in
# parentheses if you print it.
def get_next_target(page):
start_link = page.find('
【注意】
return之后,script就终止了。参见SO
median
# numbers as its inputs, and returns the median
# of the three numbers.
# Make sure your procedure has a return statement.
def bigger(a,b):
if a > b:
return a
else:
return b
def biggest(a,b,c):
return bigger(a,bigger(b,c))
# my code here:
'''
其实比较简单是再写一个求最小值的function,然后求和,依次减去最大最小值就好了。
但是我看udacity既然已经给了我们 求两者、三者最大值的functions,
应该是让我们只用这两个做。也不是不能做。
'''
def median(a, b, c):
ab_smaller = a + b - bigger(a, b)
bc_smaller = b + c - bigger(b, c)
ac_smaller = a + c - bigger(a, c)
return biggest(ab_smaller, bc_smaller, ac_smaller)
上面可以写简单点一行搞定:
def median(a, b, c):
return biggest(a + b - bigger(a, b), b + c - bigger(b, c), a + c - bigger(a, c))
Udacity的解法是,先找出biggest,然后用三个if句,if biggest == a, 那么return bigger(b, c). 以此类推。
stamps
# Define a procedure, stamps, which takes as its input a positive integer in
# pence and returns the number of 5p, 2p and 1p stamps (p is pence) required
# to make up that value. The return value should be a tuple of three numbers
# (that is, your return statement should be followed by the number of 5p,
# the number of 2p, and the nuber of 1p stamps).
#
# Your answer should use as few total stamps as possible by first using as
# many 5p stamps as possible, then 2 pence stamps and finally 1p stamps as
# needed to make up the total.
#
# (No fair for USians to just say use a "Forever" stamp and be done with it!)
#
def stamps(n):
# Your code here
five = (n - (n % 5))/5
two = ((n - five*5) - (n - five*5) % 2) / 2
one = (n - five*5 - two*2)/1
return five, two, one
print stamps(8)
#>>> (1, 1, 1) # one 5p stamp, one 2p stamp and one 1p stamp
print stamps(5)
#>>> (1, 0, 0) # one 5p stamp, no 2p stamps and no 1p stamps
print stamps(29)
#>>> (5, 2, 0) # five 5p stamps, two 2p stamps and no 1p stamps
print stamps(0)
#>>> (0, 0, 0) # no 5p stamps, no 2p stamps and no 1p stamps
Superhero Nuisance
# By Sam the Great from forums
# That freaking superhero has been frequenting Udacity
# as his favorite boss battle fight stage. The 'Udacity'
# banner keeps breaking, and money is being wasted on
# repairs. This time, we need you to proceduralize the
# fixing process by building a machine to automatically
# search through debris and return the 'Udacity' banner
# to the company, and be able to similarly fix other goods.
# Write a Python procedure fix_machine to take 2 string inputs
# and returns the 2nd input string as the output if all of its
# characters can be found in the 1st input string and "Give me
# something that's not useless next time." if it's impossible.
# Letters that are present in the 1st input string may be used
# as many times as necessary to create the 2nd string (you
# don't need to keep track of repeat usage).
# NOTE: # If you are experiencing difficulties taking
# this problem seriously, please refer back to
# "Superhero flyby", the prequel, in Problem Set 11.
# TOOLS: # if statement
# while loop
# string operations
# Unit 1 Basics
# BONUS: #
# 5***** # If you've graduated from CS101,
# Gold # try solving this in one line.
# Stars! #
def fix_machine(debris, product):
### WRITE YOUR CODE HERE ###
r = product
for i in product:
if i not in debris:
r = "Give me something that's not useless next time."
break
return r
### TEST CASES ###
print "Test case 1: ", fix_machine('UdaciousUdacitee', 'Udacity') == "Give me something that's not useless next time."
print "Test case 2: ", fix_machine('buy me dat Unicorn', 'Udacity') == 'Udacity'
print "Test case 3: ", fix_machine('AEIOU and sometimes y... c', 'Udacity') == 'Udacity'
print "Test case 4: ", fix_machine('wsx0-=mttrhix', 't-shirt') == 't-shirt'
Days Old
# By Websten from forums
#
# Given your birthday and the current date, calculate your age in days.
# Account for leap days.
#
# Assume that the birthday and current date are correct dates (and no
# time travel).
def two_digit_date(x):
if x<10:
return "0" + str(x)
else:
return str(x)
def daysBetweenDates(year1, month1, day1, year2, month2, day2):
# Your code here.
# months
r = 0
m_day = {1 : 31, 2 : 28, 3: 31, 4 : 30, 5 : 31, 6 : 30, 7 : 31, 8 : 31, 9 : 30, 10 : 31, 11 : 30, 12 : 31}
# 情况[1]
if year1 == year2:
if month1 == month2:
r = day2 - day1 + 1
if month1 == 2 and day1 <= 29 and day2 == 29:
r = r-1
else:
for i in range(month1, month2): #算month1到month2-1
r += m_day[i]
r = r-day1+1
r = r+day2
# 情况[2]
else:
# 算第一年,leap year最后算
for i in range(month1, 13):
r += m_day[i]
r = r - day1 + 1
print "start_year", r
# 算最后一年,leap year最后算
for i in range(1, month2):
r += m_day[i]
r += day2
print "end_year", r
# 算中间年,leap year最后算
r += 365*(year2-year1-1)
print "between_year", r
# 收尾,算闰年
# 把年份转换成数字,譬如20100101
# 最终是比较数字大小,因此年份不足4位不用加0,但是月份和日期不足2位要加0
start_date = int(str(year1) + two_digit_date(month1) + two_digit_date(day1))
end_date = int(str(year2) + two_digit_date(month2) + two_digit_date(day2))
print start_date, end_date
print r
print range(year1, year2+1)
leap_days = 0
for i in range(year1, year2+1):
if i % 4 == 0:
leap_date = int(str(i) + "0229")
if leap_date >= start_date and leap_date <= end_date:
leap_days += 1
if i % 100 == 0 and i % 400 != 0:
leap_days -= 1 #四年一闰 百年不闰 四百年再闰
print "add", leap_date
r += leap_days
return r-1 #因为是算活了多少天,是跨度,间隔问题,要减一
def test():
test_cases = [((2012,1,1,2012,2,28), 58),
((2012,1,1,2012,3,1), 60),
((2011,6,30,2012,6,30), 366),
((2011,1,1,2012,8,8), 585 ),
((1900,1,1,1999,12,31), 36523)]
for (args, answer) in test_cases:
result = daysBetweenDates(*args)
if result != answer:
print "Test with data:", args, "failed"
else:
print "Test case passed!"
test()
脱水版:
def two_digit_date(x):
if x<10:
return "0" + str(x)
else:
return str(x)
def daysBetweenDates(year1, month1, day1, year2, month2, day2):
r = 0
m_day = {1 : 31, 2 : 28, 3: 31, 4 : 30, 5 : 31, 6 : 30, 7 : 31, 8 : 31, 9 : 30, 10 : 31, 11 : 30, 12 : 31}
if year1 == year2:
if month1 == month2:
r = day2 - day1 + 1
if month1 == 2 and day1 <= 29 and day2 == 29:
r = r-1
else:
for i in range(month1, month2):
r += m_day[i]
r = r-day1+1
r = r+day2
else:
for i in range(month1, 13):
r += m_day[i]
r = r - day1 + 1
for i in range(1, month2):
r += m_day[i]
r += day2
r += 365*(year2-year1-1)
start_date = int(str(year1) + two_digit_date(month1) + two_digit_date(day1))
end_date = int(str(year2) + two_digit_date(month2) + two_digit_date(day2))
leap_days = 0
for i in range(year1, year2+1):
if i % 4 == 0:
leap_date = int(str(i) + "0229")
if leap_date >= start_date and leap_date <= end_date:
leap_days += 1
if i % 100 == 0 and i % 400 != 0:
leap_days -= 1
r += leap_days
return r-1
abacus
#########################################################################
# 10-row School abacus
# by
# Michael H
#########################################################################
# Description partially extracted from from wikipedia
#
# Around the world, abaci have been used in pre-schools and elementary
#
# In Western countries, a bead frame similar to the Russian abacus but
# with straight wires and a vertical frame has been common (see image).
# Helps schools as an aid in teaching the numeral system and arithmetic
#
# |00000***** | row factor 1000000000
# |00000***** | row factor 100000000
# |00000***** | row factor 10000000
# |00000***** | row factor 1000000
# |00000***** | row factor 100000
# |00000***** | row factor 10000
# |00000***** | row factor 1000
# |00000**** *| row factor 100 * 1
# |00000*** **| row factor 10 * 2
# |00000** ***| row factor 1 * 3
# -----------
# Sum 123
#
# Each row represents a different row factor, starting with x1 at the
# bottom, ascending up to x1000000000 at the top row.
######################################################################
# TASK:
# Define a procedure print_abacus(integer) that takes a positive integer
# and prints a visual representation (image) of an abacus setup for a
# given positive integer value.
#
# Ranking
# 1 STAR: solved the problem!
# 2 STARS: 6 < lines <= 9
# 3 STARS: 3 < lines <= 6
# 4 STARS: 0 < lines <= 3
def print_abacus(value):
value = "0"*(10-len(str(value))) + str(value)
abacus_line = "00000*****"
for i in value:
digit = int(i)
print "|" + abacus_line[:10-digit] + " " + abacus_line[10-digit:] + "|"
### TEST CASES
print "Abacus showing 0:"
print_abacus(0)
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
print "Abacus showing 12345678:"
print_abacus(12345678)
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000**** *|
#>>>|00000*** **|
#>>>|00000** ***|
#>>>|00000* ****|
#>>>|00000 *****|
#>>>|0000 0*****|
#>>>|000 00*****|
#>>>|00 000*****|
print "Abacus showing 1337:"
print_abacus(1337)
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000***** |
#>>>|00000**** *|
#>>>|00000** ***|
#>>>|00000** ***|
#>>>|000 00*****|
Leap year baby
# By Ashwath from forums
# A leap year baby is a baby born on Feb 29, which occurs only on a leap year.
# Define a procedure is_leap_baby that takes 3 inputs: day, month and year
# and returns True if the date is a leap day (Feb 29 in a valid leap year)
# and False otherwise.
# A year that is a multiple of 4 is a leap year unless the year is
# divisible by 100 but not a multiple of 400 (so, 1900 is not a leap
# year but 2000 and 2004 are).
def is_leap_baby(day,month,year):
# Write your code after this line.
if year % 4 == 0 and month == 2 and day == 29:
r = True
if year % 100 == 0 and year % 400 != 0:
r = False
else:
r = False
return r
# The function 'output' prints one of two statements based on whether
# the is_leap_baby function returned True or False.
def output(status,name):
if status:
print "%s is one of an extremely rare species. He is a leap year baby!" % name
else:
print "There's nothing special about %s's birthday. He is not a leap year baby!" % name
# Test Cases
output(is_leap_baby(29, 2, 1996), 'Calvin')
#>>>Calvin is one of an extremely rare species. He is a leap year baby!
output(is_leap_baby(19, 6, 1978), 'Garfield')
#>>>There's nothing special about Garfield's birthday. He is not a leap year baby!
output(is_leap_baby(29, 2, 2000), 'Hobbes')
#>>>Hobbes is one of an extremely rare species. He is a leap year baby!
output(is_leap_baby(29, 2, 1900), 'Charlie Brown')
#>>>There's nothing special about Charlie Brown's birthday. He is not a leap year baby!
output(is_leap_baby(28, 2, 1976), 'Odie')
#>>>There's nothing special about Odie's birthday. He is not a leap year baby!