mirror of
https://github.com/coursera-dl/coursera-dl.git
synced 2026-08-01 15:30:12 +00:00
Merge pull request #316 from vladistan/refactor_and_coverage
Add lots of refactoring and tests. Courtesy of @vladistan.
This commit is contained in:
commit
402c7d6a64
7 changed files with 273 additions and 40 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -4,7 +4,8 @@
|
|||
_cache/
|
||||
.coverage
|
||||
/cover/
|
||||
|
||||
# virtualenv folders
|
||||
venv2
|
||||
venv3
|
||||
.idea
|
||||
.python-version
|
||||
|
|
|
|||
|
|
@ -312,6 +312,53 @@ def download_about(session, class_name, path='', overwrite=False):
|
|||
break
|
||||
|
||||
|
||||
def is_course_complete(last_update):
|
||||
rv = False
|
||||
if last_update >= 0:
|
||||
delta = time.time() - last_update
|
||||
max_delta = total_seconds(datetime.timedelta(days=30))
|
||||
if delta > max_delta:
|
||||
rv = True
|
||||
return rv
|
||||
|
||||
|
||||
def format_section(num, section, class_name, verbose_dirs ):
|
||||
sec = '%02d_%s' % (num, section)
|
||||
if verbose_dirs:
|
||||
sec = class_name.upper() + '_' + sec
|
||||
return sec
|
||||
|
||||
|
||||
def format_resource(num, name, title, fmt):
|
||||
if title:
|
||||
title = '_' + title
|
||||
return '%02d_%s%s.%s' % (num, name, title, fmt)
|
||||
|
||||
|
||||
def format_combine_number_resource(secnum, lecnum, lecname, title, fmt):
|
||||
if title:
|
||||
title = '_' + title
|
||||
return '%02d_%02d_%s%s.%s' % (secnum, lecnum, lecname, title, fmt)
|
||||
|
||||
|
||||
def find_resources_to_get(lecture, file_formats, resource_filter):
|
||||
# Select formats to download
|
||||
resources_to_get = []
|
||||
for fmt, resources in iteritems(lecture):
|
||||
if fmt in file_formats or 'all' in file_formats:
|
||||
for r in resources:
|
||||
if resource_filter and r[1] and not re.search(resource_filter, r[1]):
|
||||
logging.debug('Skipping b/c of rf: %s %s',
|
||||
resource_filter, r[1])
|
||||
continue
|
||||
resources_to_get.append((fmt, r[0], r[1]))
|
||||
else:
|
||||
logging.debug(
|
||||
'Skipping b/c format %s not in %s', fmt, file_formats)
|
||||
|
||||
return resources_to_get
|
||||
|
||||
|
||||
def download_lectures(downloader,
|
||||
class_name,
|
||||
sections,
|
||||
|
|
@ -335,30 +382,14 @@ def download_lectures(downloader,
|
|||
"""
|
||||
last_update = -1
|
||||
|
||||
def format_section(num, section):
|
||||
sec = '%02d_%s' % (num, section)
|
||||
if verbose_dirs:
|
||||
sec = class_name.upper() + '_' + sec
|
||||
return sec
|
||||
|
||||
def format_resource(num, name, title, fmt):
|
||||
if title:
|
||||
title = '_' + title
|
||||
return '%02d_%s%s.%s' % (num, name, title, fmt)
|
||||
|
||||
def format_combine_number_resource(secnum, lecnum, lecname, title, fmt):
|
||||
if title:
|
||||
title = '_' + title
|
||||
return '%02d_%02d_%s%s.%s' % (secnum, lecnum, lecname, title, fmt)
|
||||
|
||||
for (secnum, (section, lectures)) in enumerate(sections):
|
||||
if section_filter and not re.search(section_filter, section):
|
||||
logging.debug('Skipping b/c of sf: %s %s', section_filter,
|
||||
section)
|
||||
continue
|
||||
|
||||
sec = os.path.join(path, class_name, format_section(secnum + 1,
|
||||
section))
|
||||
sec = os.path.join(path, class_name,
|
||||
format_section(secnum + 1, section, class_name, verbose_dirs))
|
||||
for (lecnum, (lecname, lecture)) in enumerate(lectures):
|
||||
if lecture_filter and not re.search(lecture_filter,
|
||||
lecname):
|
||||
|
|
@ -369,19 +400,7 @@ def download_lectures(downloader,
|
|||
if not os.path.exists(sec):
|
||||
mkdir_p(sec)
|
||||
|
||||
# Select formats to download
|
||||
resources_to_get = []
|
||||
for fmt, resources in iteritems(lecture):
|
||||
if fmt in file_formats or 'all' in file_formats:
|
||||
for r in resources:
|
||||
if resource_filter and r[1] and not re.search(resource_filter, r[1]):
|
||||
logging.debug('Skipping b/c of rf: %s %s',
|
||||
resource_filter, r[1])
|
||||
continue
|
||||
resources_to_get.append((fmt, r[0], r[1]))
|
||||
else:
|
||||
logging.debug(
|
||||
'Skipping b/c format %s not in %s', fmt, file_formats)
|
||||
resources_to_get = find_resources_to_get(lecture, file_formats, resource_filter)
|
||||
|
||||
# write lecture resources
|
||||
for fmt, url, title in resources_to_get:
|
||||
|
|
@ -431,13 +450,10 @@ def download_lectures(downloader,
|
|||
|
||||
# if we haven't updated any files in 1 month, we're probably
|
||||
# done with this course
|
||||
if last_update >= 0:
|
||||
delta = time.time() - last_update
|
||||
max_delta = total_seconds(datetime.timedelta(days=30))
|
||||
if delta > max_delta:
|
||||
logging.info('COURSE PROBABLY COMPLETE: ' + class_name)
|
||||
return True
|
||||
return False
|
||||
rv = is_course_complete(last_update)
|
||||
if rv:
|
||||
logging.info('COURSE PROBABLY COMPLETE: ' + class_name)
|
||||
return rv
|
||||
|
||||
|
||||
def total_seconds(td):
|
||||
|
|
|
|||
25
coursera/test/fixtures/json/matrix-002-about.json
vendored
Normal file
25
coursera/test/fixtures/json/matrix-002-about.json
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"video":"IWugXcWpfoM",
|
||||
"links":{},
|
||||
"estimatedClassWorkload":"7-10 hours/week",
|
||||
"instructor":"Phil Klein",
|
||||
"largeIcon":"https://d15cw65ipctsrr.cloudfront.net/6c/ffdfc097878bc0f8115148d7ee6826/460_259_logo.jpg",
|
||||
"id":198,
|
||||
"smallIconHover":"https://d15cw65ipctsrr.cloudfront.net/c9/8b3a8357fe29791971ece8cc8fb35b/460_259_logo.jpg",
|
||||
"universityLogo":"",
|
||||
"smallIcon":"https://d15cw65ipctsrr.cloudfront.net/c9/8b3a8357fe29791971ece8cc8fb35b/460_259_logo.jpg",
|
||||
"faq":"<ul><li><b>Will I get a statement of accomplishment after completing this class?<br></b><br>Yes. Students who successfully complete the class will receive a statement of accomplishment signed by the instructor.<br><br></li><li><b>What resources will I need for this class?</b><br><br>You will need a computer with Python installed (version 3.x). We will provide additional Python modules for you to download.<br><br></li><li><b>What is the coolest thing I'll learn if I take this class?</b><br><br>Here are some cool things: removing the perspective from an image, a simple machine-learning algorithm applied to cancer data.</li></ul>",
|
||||
"universityLogoSt":"",
|
||||
"courseSyllabus":"<ul><li>The Function</li><li>The Field</li><li>The Vector</li><li>The Vector Space</li><li>The Matrix</li><li>The Basis</li><li>Dimension</li><li>Gaussian Elimination</li><li>The Inner Product</li><li>Orthogonalization</li></ul>",
|
||||
"shortName":"matrix",
|
||||
"targetAudience":0,
|
||||
"shortDescription":"Learn the concepts and methods of linear algebra, and how to use them to think about computational problems arising in computer science. Coursework includes building on the concepts to write small programs and run them on real data. ",
|
||||
"aboutTheCourse":"<div>When you take a digital photo with your phone or transform the image in Photoshop, when you play a video game or watch a movie with digital effects, when you do a web search or make a phone call, you are using technologies that build upon linear algebra. Linear algebra provides concepts that are crucial to many areas of computer science, including graphics, image processing, cryptography, machine learning, computer vision, optimization, graph algorithms, quantum computation, computational biology, information retrieval and web search. Linear algebra in turn is built on two basic elements, the matrix and the vector. </div><div><br></div><div>In this class, you will learn the concepts and methods of linear algebra, and how to use them to think about problems arising in computer science. You will write small programs in the programming language Python to implement basic matrix and vector functionality and algorithms, and use these to process real-world data to achieve such tasks as: two-dimensional graphics transformations, face morphing, face detection, image transformations such as blurring and edge detection, image perspective removal, classification of tumors as malignant or benign, integer factorization, error-correcting codes, and secret-sharing.</div><div><br></div>",
|
||||
"videoId":"IWugXcWpfoM",
|
||||
"courseFormat":"",
|
||||
"aboutTheInstructor":"<div><div><img class=\"coursera-instructor-thumb\" src=\"https://coursera-topic-photos.s3.amazonaws.com/db/2b950a6da9c516b9b88cac1e15080b/klein_photo.jpg\"><br>Philip Klein is Professor of Computer Science at Brown University. \u00a0He was a recipient of the National Science Foundation's Presidential Young Investigator Award, and has received multiple research grants from the National Science Foundation. \u00a0He has been made an ACM Fellow in recognition of his contributions to research on graph algorithms. He is a recipient of Brown University's Award for Excellence in Teaching in the Sciences.\u00a0</div><div><br></div><div>Klein received a B.A. in Applied Mathematics from Harvard and a Ph.D. in Computer Science from MIT. \u00a0He has been a Visiting Scientist at Princeton's Computer Science Department, at MIT's Mathematics Department, and at MIT's Computer Science and Artificial Intelligence Laboratory (CSAIL), where he is currently a Research Affiliate.\u00a0</div><div><br></div><div>Klein has worked at industry research labs, including Xerox PARC and AT&T Labs. \u00a0He has been Chief Scientist at three successful start-ups.\u00a0</div></div>",
|
||||
"recommendedBackground":"You should be an experienced programmer. We use a subset of Python in this course, and we start by covering the relevant features and syntax, so many students find they can get by without prior knowledge of Python.<br><br>You are <i>not</i> expected to have any background in linear algebra. However, you should be prepared to read and understand some mathematical proofs. At Brown University, a similar course is taken mostly by sophomore computer science majors who have taken at least two semesters of programming and one semester addressing proof techniques.<br>",
|
||||
"name":"Coding the Matrix: Linear Algebra through Computer Science Applications",
|
||||
"suggestedReadings":"<a href=\"http://www.amazon.com/dp/0615880991/\" target=\"_blank\">Coding the Matrix</a> is an optional companion textbook. \u00a0It covers the material addressed by this course, plus additional examples and more advanced topics not covered by the course (wavelets, discrete Fourier transforms, singular value decomposition, eigenvalues, and linear programming). \u00a0The textbook is not at all necessary for taking the course; all necessary material is covered in lecture. \u00a0",
|
||||
"photo":"https://coursera-course-photos.s3.amazonaws.com/ec/6faacf42b19cf2772061ae095d98ee/460_259_logo.jpg"
|
||||
}
|
||||
77
coursera/test/fixtures/json/unprocessed.json
vendored
Normal file
77
coursera/test/fixtures/json/unprocessed.json
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"elements": [
|
||||
{
|
||||
"aboutTheCourse": "<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439\n\u043a\u0443\u0440\u0441 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u044b, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0438 \u043c\u043d\u043e\u0433\u043e\u043c\u0435\u0440\u043d\u043e\u0433\u043e\n\u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b, \u043d\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435\n\u0434\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0430.</p>\n\n<p>\u041c\u044b \u0432\u0432\u0435\u0434\u0451\u043c\n\u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0441\u0442\u0438 \u0438 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430, \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430,\n\u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430. \u041d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u0430\u043c\u0438,\n\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u0443\u0434\u0430\u0447\u043d\u044b\u0435 \u0431\u0430\u0437\u0438\u0441\u044b \u0434\u043b\u044f \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 (\u0434\u0438\u0430\u0433\u043e\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u0443,\n\u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043d\u0430\u0439\u0442\u0438 \u0436\u043e\u0440\u0434\u0430\u043d\u043e\u0432 \u0431\u0430\u0437\u0438\u0441 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439\n\u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u0438). \u041c\u044b \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u0442\u0435\u043e\u0440\u0435\u043c\u0443 \u041f\u0435\u0440\u0440\u043e\u043d\u0430-\u0424\u0440\u043e\u0431\u0435\u043d\u0438\u0443\u0441\u0430\n\u0438 \u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0437\u0443\u0447\u0430\u0442\u044c\n\u043a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u044b \u0438 \u0438\u0445 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043a \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u043e\u0441\u044f\u043c. </p>\n\n<p> </p>\n\n<p>This is\na standard course in Linear Algebra. It covers all topics applicable to\nStatistics and Multivariable Calculus, but does not always give explicit\nproofs. </p>\n\n<p>We will\nintroduce the notions of linearity, vector space, finite-dimensional space,\nlinear functional, linear operator. During the course we will learn how to\noperate with matrices, how to find matrix diagonalization, if possible,\nand Jordan basis for spaces of small dimension. We will mention\nPerron\u2013Frobenius theorem and its applications to Web indexing. Also, we will\nstudy quadratic forms and its reduction to canonical form.</p>",
|
||||
"courseFormat": "\u041a\u0430\u0436\u0434\u0430\u044f \u043b\u0435\u043a\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437\n\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u0438\u0434\u0435\u043e\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043e\u0432, \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 10 \u043c\u0438\u043d\u0443\u0442, \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438\n\u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f. \u041a \u043a\u0430\u0436\u0434\u043e\u0439 \u043b\u0435\u043a\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0440\u0430\u0431\u043e\u0442\u0430. \u041a\u0443\u0440\u0441\n\u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0434\u0432\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u0445 \u0440\u0430\u0431\u043e\u0442\u044b \u2013 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u0438 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u044d\u043a\u0437\u0430\u043c\u0435\u043d. \u041c\u044b\n\u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u043e\u043c\u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u044f\n\u043a\u0443\u0440\u0441\u0430 \u043f\u043e\u043a\u0430\u0436\u0443\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438.",
|
||||
"courseSyllabus": "<p><strong>\u041d\u0435\u0434\u0435\u043b\u044f 1.</strong>\n\u041b\u0438\u043d\u0435\u0439\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e.</p><p><strong>\u041d\u0435\u0434\u0435\u043b\u044f 2. </strong>\u041b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b. \u041b\u0438\u043d\u0435\u0439\u043d\u043e\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.</p>\n\n<p><strong>\u041d\u0435\u0434\u0435\u043b\u044f 3.</strong>\n\u0411\u0430\u0437\u0438\u0441 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c.</p>\n\n<p><span><strong>\u041d\u0435\u0434\u0435\u043b\u044f 4. </strong>\u041c\u0435\u0442\u043e\u0434\n\u0413\u0430\u0443\u0441\u0441\u0430. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0445 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0439. \n</span></p>\n\n<p><strong>\u041d\u0435\u0434\u0435\u043b\u044f 5.</strong> \u041c\u0430\u0442\u0440\u0438\u0446\u0430 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u0431\u0430\u0437\u0438\u0441\u0443.</p>\n\n<p><strong>\u041d\u0435\u0434\u0435\u043b\u044f 6.</strong>\n\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u044b. \u041b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440.</p>\n\n<p><strong>\u041d\u0435\u0434\u0435\u043b\u044f 7.\n</strong>\u0417\u0430\u043c\u0435\u043d\u0430 \u0431\u0430\u0437\u0438\u0441\u0430 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u044b, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f,\n\u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0431\u0430\u0437\u0438\u0441.</p>\n\n<p><strong>\u041d\u0435\u0434\u0435\u043b\u044f 8.</strong>\n\u0416\u043e\u0440\u0434\u0430\u043d\u043e\u0432\u0430 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u043e\u0440\u043c\u0430. \u0421\u0436\u0438\u043c\u0430\u044e\u0449\u0438\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0422\u0435\u043e\u0440\u0435\u043c\u0430 \u0424\u0440\u043e\u0431\u0435\u043d\u0438\u0443\u0441\u0430.</p>\n\n<p><strong>\u041d\u0435\u0434\u0435\u043b\u044f 9.</strong>\n\u0411\u0438\u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u044b. \u041a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u044b.</p>\n\n<p><strong>\u041d\u0435\u0434\u0435\u043b\u044f 10.</strong> \u041e\u0440\u0442\u043e\u0433\u043e\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f.\n\u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0444\u043e\u0440\u043c\u044b \u043a \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u043e\u0441\u044f\u043c.</p>\n\n<strong>\u041d\u0435\u0434\u0435\u043b\u044f 11. </strong>\u041c\u0435\u0442\u043e\u0434 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0438\u0445 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043e\u0432.",
|
||||
"estimatedClassWorkload": "4-6 hours/week",
|
||||
"faq": "<p><strong>\u042f \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u0443\u0447\u0435\u0431\u043d\u0438\u043a \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u0432 \u043d\u0435\u043c \u043d\u0435 \u043f\u043e\u043d\u044f\u043b. \u0417\u043d\u0430\u0447\u0438\u0442 \u043b\u0438 \u044d\u0442\u043e, \u0447\u0442\u043e \u044f \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\n\u0441\u043b\u0443\u0448\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441?</strong></p>\n\n\u041d\u0435\u0442, \u043d\u0435 \u0437\u043d\u0430\u0447\u0438\u0442. \u041c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043b\u0438\u0442\u0435\u0440\u0430\u0442\u0443\u0440\u0430\n\u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0441\u0436\u0430\u0442\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0432 \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0439 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u0438, \u0435\u0435\n\u0442\u0440\u0443\u0434\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u0441 \u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e, \u0432\u0441\u0451 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\n\u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e.",
|
||||
"id": 2462,
|
||||
"largeIcon": "https://d15cw65ipctsrr.cloudfront.net/56/2a54805dc611e4994553981ebb0a30/LA.png",
|
||||
"links": {},
|
||||
"name": "\u041b\u0438\u043d\u0435\u0439\u043d\u0430\u044f \u0430\u043b\u0433\u0435\u0431\u0440\u0430 (Linear Algebra)",
|
||||
"photo": "https://d15cw65ipctsrr.cloudfront.net/55/1b2e705dc611e4b2ae9b6d330ca688/LA.png",
|
||||
"recommendedBackground": "<span>\n <span><span>\n <span>\n <p>\u0414\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043a\u0443\u0440\u0441\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u043d\u0438\u044f\n \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u0448\u043a\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u0443\u0440\u0441\u0430 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0438.</p>\n </span>\n </span>\n</span></span>",
|
||||
"shortDescription": "\u041a\u0443\u0440\u0441 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u044b \u0434\u043b\u044f \u043d\u0435\u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0444\u0430\u043a\u0443\u043b\u044c\u0442\u0435\u0442\u043e\u0432",
|
||||
"shortName": "linalg",
|
||||
"smallIcon": "https://d15cw65ipctsrr.cloudfront.net/56/2858b05dc611e48f12553b288c8434/LA.png",
|
||||
"smallIconHover": "https://d15cw65ipctsrr.cloudfront.net/56/2858b05dc611e48f12553b288c8434/LA.png",
|
||||
"suggestedReadings": "<p>\u0418. \u041c. \u0413\u0435\u043b\u044c\u0444\u0430\u043d\u0434.\n\u041b\u0435\u043a\u0446\u0438\u0438 \u043f\u043e \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u0435.</p>\n\n<p>\u0410. \u0418. \u041a\u043e\u0441\u0442\u0440\u0438\u043a\u0438\u043d, \u042e. \u0418. \u041c\u0430\u043d\u0438\u043d. \u041b\u0438\u043d\u0435\u0439\u043d\u0430\u044f \u0430\u043b\u0433\u0435\u0431\u0440\u0430 \u0438 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044f.</p>\u042d. \u0411. \u0412\u0438\u043d\u0431\u0435\u0440\u0433. \u041a\u0443\u0440\u0441 \u0430\u043b\u0433\u0435\u0431\u0440\u044b.",
|
||||
"targetAudience": 0,
|
||||
"universityLogo": "",
|
||||
"universityLogoSt": "",
|
||||
"video": "0f515f9079ff11e4b62aeb5925a4c57e",
|
||||
"videoId": "0f515f9079ff11e4b62aeb5925a4c57e"
|
||||
},
|
||||
{
|
||||
"aboutTheCourse": "<div>Social networks pervade our social and economic lives. \u00a0 They play a central role in the transmission of information about job opportunities and are critical to the trade of many goods and services. They are important in determining which products we buy, which languages we speak, how we vote, as well as whether or not we decide to become criminals, how much education we obtain, and our likelihood of succeeding professionally. \u00a0 The countless ways in which network structures affect our well-being make it critical to understand how social network structures impact behavior, which network structures are likely to emerge in a society, and why we organize ourselves as we do. \u00a0This course provides an overview and synthesis of research on social and economic networks, drawing on studies by sociologists, economists, computer scientists, physicists, and mathematicians.</div><div><br></div><div>The course begins with some empirical background on\u00a0social and economic networks, and an overview of concepts used to\u00a0describe and measure networks. \u00a0 Next, we will cover a set of\u00a0models of how networks form, including random network models as well as\u00a0strategic formation models, and some hybrids. \u00a0 We will then discuss a series of\u00a0models of how networks impact behavior, including contagion, diffusion, learning, and peer influences.</div><div><br></div>",
|
||||
"aboutTheInstructor": "",
|
||||
"courseFormat": "<p>The course will run for seven weeks, plus two for the final exam. Each week there will be\nvideo lectures available, as well as a standalone problem set and some occasional data\nexercises, and there will be a final exam at the end of the course for those who wish to earn a course certificate. </p>",
|
||||
"courseSyllabus": "<ul><li>Week 1:\u00a0Introduction, Empirical Background and Definitions<br></li></ul>Examples of Social Networks and their Impact, Definitions, Measures and Properties: Degrees, Diameters, Small Worlds, Weak and Strong Ties, Degree Distributions<br><br><ul><li>Week 2: Background, Definitions, and Measures\u00a0Continued</li></ul>Homophily, Dynamics, \u00a0Centrality Measures: Degree, Betweenness, Closeness, Eigenvector, and Katz-Bonacich.\u00a0Erdos and Renyi Random Networks:\u00a0Thresholds and Phase Transitions,<br><br><ul><li>Week 3:\u00a0Random Networks\u00a0<br></li></ul>Poisson Random Networks, Exponential Random Graph Models, \u000f Growing Random Networks, Preferential Attachment and Power Laws, Hybrid models of Network Formation<br><br><ul><li>Week 4: \u00a0\u000f Strategic Network Formation\u00a0</li></ul><div>Game Theoretic Modeling of Network Formation, The Connections Model, The Conflict between Incentives and E\u000efficiency, Dynamics, Directed Networks, Hybrid Models of Choice and Chance<br><br></div><ul><li>Week 5:\u00a0\u00a0Di\u000bffusion on Networks.\u00a0</li></ul>Empirical Background, The Bass Model,\u00a0Random Network Models of Contagion, The SIS model, Fitting a Simulated Model to Data<br><br><ul><li>Week 6:\u00a0\u00a0Learning on Networks.\u00a0</li></ul>Bayesian Learning on Networks, The DeGroot Model of\u00a0Learning on a Network, Convergence of Beliefs, The Wisdom of Crowds, How Influence depends on Network Position.<br><br><ul><li>Week 7:\u00a0Games on Networks.\u00a0</li></ul><div>Network Games, Peer Influences: \u00a0Strategic\u00a0Complements and Substitutes, the Relation between Network Structure and Behavior, A Linear Quadratic Game,\u00a0Repeated Interactions and Network Structures.</div><div><br></div>",
|
||||
"estimatedClassWorkload": "3-6 hours/week",
|
||||
"faq": "<strong>Will I get a Statement of Accomplishment after completing this class?</strong><p>Yes. Students who successfully complete the class (above 70 percent correct on the problem sets and final exam) will receive a Statement of Accomplishment signed by the instructor - and those earning above 90 percent credit on the problem sets and final will earn one with distinction.</p>",
|
||||
"id": 394,
|
||||
"instructor": "Matthew O. Jackson",
|
||||
"largeIcon": "https://d15cw65ipctsrr.cloudfront.net/1c/38d188bf97105025168a55aebc634a/Logo1.jpg",
|
||||
"links": {},
|
||||
"name": "Social and Economic Networks: Models and Analysis",
|
||||
"photo": "https://coursera-course-photos.s3.amazonaws.com/ec/50a9bcc99dfc058198c9d4827b11e7/Logo1.jpg",
|
||||
"recommendedBackground": "The course has some basic prerequisites in mathematics and statistics. \u00a0For example, it will be assumed that students are comfortable with basic concepts from linear algebra (e.g., matrix multiplication), probability theory (e.g., probability distributions, expected values, Bayes' rule), and statistics (e.g., hypothesis testing), and some light calculus (e.g., differentiation and integration). \u00a0Beyond those concepts, the course will be self-contained.",
|
||||
"shortDescription": "Learn how to model social and economic networks and their impact on human behavior. How do networks form, why do they exhibit certain patterns, and how does their structure impact diffusion, learning, and other behaviors? We will bring together models and techniques from economics, sociology, math, physics, statistics and computer science to answer these questions. ",
|
||||
"shortName": "networksonline",
|
||||
"smallIcon": "https://d15cw65ipctsrr.cloudfront.net/1a/0fd0bcaded566342c65e16db568094/Logo1.jpg",
|
||||
"smallIconHover": "https://d15cw65ipctsrr.cloudfront.net/1a/0fd0bcaded566342c65e16db568094/Logo1.jpg",
|
||||
"suggestedReadings": "The course is self-contained, so that all the definitions and concepts you need to solve the problem sets and final are contained in the video lectures. Much of the material for the course is covered in a text: Matthew O. Jackson Social and Economic Networks, Princeton University Press (Here are <a href=\"http://press.princeton.edu/titles/8767.html\">Princeton University Press</a> and\n<a href=\"http://www.amazon.com/Social-Economic-Networks-Matthew-Jackson/dp/0691148201/ref=tmm_pap_title_0\">Amazon</a> pages for the book). The text is <i>optional</i> and not required for the course. Additional background readings, including research articles and several surveys on some of the topics covered in the course can be found on <a href=\"http://www.stanford.edu/~jacksonm/papersarticles.html\">my web page</a>.",
|
||||
"targetAudience": 2,
|
||||
"universityLogo": "",
|
||||
"video": "mjS81EoBQOU",
|
||||
"videoId": "mjS81EoBQOU"
|
||||
},
|
||||
{
|
||||
"aboutTheCourse": "<div>When you take a digital photo with your phone or transform the image in Photoshop, when you play a video game or watch a movie with digital effects, when you do a web search or make a phone call, you are using technologies that build upon linear algebra. Linear algebra provides concepts that are crucial to many areas of computer science, including graphics, image processing, cryptography, machine learning, computer vision, optimization, graph algorithms, quantum computation, computational biology, information retrieval and web search. Linear algebra in turn is built on two basic elements, the matrix and the vector. </div><div><br></div><div>In this class, you will learn the concepts and methods of linear algebra, and how to use them to think about problems arising in computer science. You will write small programs in the programming language Python to implement basic matrix and vector functionality and algorithms, and use these to process real-world data to achieve such tasks as: two-dimensional graphics transformations, face morphing, face detection, image transformations such as blurring and edge detection, image perspective removal, classification of tumors as malignant or benign, integer factorization, error-correcting codes, and secret-sharing.</div><div><br></div>",
|
||||
"aboutTheInstructor": "<div><div><img class=\"coursera-instructor-thumb\" src=\"https://coursera-topic-photos.s3.amazonaws.com/db/2b950a6da9c516b9b88cac1e15080b/klein_photo.jpg\"><br>Philip Klein is Professor of Computer Science at Brown University. \u00a0He was a recipient of the National Science Foundation's Presidential Young Investigator Award, and has received multiple research grants from the National Science Foundation. \u00a0He has been made an ACM Fellow in recognition of his contributions to research on graph algorithms. He is a recipient of Brown University's Award for Excellence in Teaching in the Sciences.\u00a0</div><div><br></div><div>Klein received a B.A. in Applied Mathematics from Harvard and a Ph.D. in Computer Science from MIT. \u00a0He has been a Visiting Scientist at Princeton's Computer Science Department, at MIT's Mathematics Department, and at MIT's Computer Science and Artificial Intelligence Laboratory (CSAIL), where he is currently a Research Affiliate.\u00a0</div><div><br></div><div>Klein has worked at industry research labs, including Xerox PARC and AT&T Labs. \u00a0He has been Chief Scientist at three successful start-ups.\u00a0</div></div>",
|
||||
"courseFormat": "",
|
||||
"courseSyllabus": "<ul><li>The Function</li><li>The Field</li><li>The Vector</li><li>The Vector Space</li><li>The Matrix</li><li>The Basis</li><li>Dimension</li><li>Gaussian Elimination</li><li>The Inner Product</li><li>Orthogonalization</li></ul>",
|
||||
"estimatedClassWorkload": "7-10 hours/week",
|
||||
"faq": "<ul><li><b>Will I get a statement of accomplishment after completing this class?<br></b><br>Yes. Students who successfully complete the class will receive a statement of accomplishment signed by the instructor.<br><br></li><li><b>What resources will I need for this class?</b><br><br>You will need a computer with Python installed (version 3.x). We will provide additional Python modules for you to download.<br><br></li><li><b>What is the coolest thing I'll learn if I take this class?</b><br><br>Here are some cool things: removing the perspective from an image, a simple machine-learning algorithm applied to cancer data.</li></ul>",
|
||||
"id": 198,
|
||||
"instructor": "Phil Klein",
|
||||
"largeIcon": "https://d15cw65ipctsrr.cloudfront.net/6c/ffdfc097878bc0f8115148d7ee6826/460_259_logo.jpg",
|
||||
"links": {},
|
||||
"name": "Coding the Matrix: Linear Algebra through Computer Science Applications",
|
||||
"photo": "https://coursera-course-photos.s3.amazonaws.com/ec/6faacf42b19cf2772061ae095d98ee/460_259_logo.jpg",
|
||||
"recommendedBackground": "You should be an experienced programmer. We use a subset of Python in this course, and we start by covering the relevant features and syntax, so many students find they can get by without prior knowledge of Python.<br><br>You are <i>not</i> expected to have any background in linear algebra. However, you should be prepared to read and understand some mathematical proofs. At Brown University, a similar course is taken mostly by sophomore computer science majors who have taken at least two semesters of programming and one semester addressing proof techniques.<br>",
|
||||
"shortDescription": "Learn the concepts and methods of linear algebra, and how to use them to think about computational problems arising in computer science. Coursework includes building on the concepts to write small programs and run them on real data. ",
|
||||
"shortName": "matrix",
|
||||
"smallIcon": "https://d15cw65ipctsrr.cloudfront.net/c9/8b3a8357fe29791971ece8cc8fb35b/460_259_logo.jpg",
|
||||
"smallIconHover": "https://d15cw65ipctsrr.cloudfront.net/c9/8b3a8357fe29791971ece8cc8fb35b/460_259_logo.jpg",
|
||||
"suggestedReadings": "<a href=\"http://www.amazon.com/dp/0615880991/\" target=\"_blank\">Coding the Matrix</a> is an optional companion textbook. \u00a0It covers the material addressed by this course, plus additional examples and more advanced topics not covered by the course (wavelets, discrete Fourier transforms, singular value decomposition, eigenvalues, and linear programming). \u00a0The textbook is not at all necessary for taking the course; all necessary material is covered in lecture. \u00a0",
|
||||
"targetAudience": 0,
|
||||
"universityLogo": "",
|
||||
"universityLogoSt": "",
|
||||
"video": "IWugXcWpfoM",
|
||||
"videoId": "IWugXcWpfoM"
|
||||
}
|
||||
],
|
||||
"linked": {}
|
||||
}
|
||||
|
|
@ -7,6 +7,36 @@ Test the downloaders.
|
|||
import unittest
|
||||
|
||||
from coursera import downloaders
|
||||
from coursera import coursera_dl
|
||||
|
||||
|
||||
class ResourceCollectorTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.sample_bag = {
|
||||
'mp4': [['h://url1/lc1.mp4', 'video']],
|
||||
'pdf': [['h://url2/lc2.pdf', 'slides']],
|
||||
'txt': [['h://url3/lc3.txt', 'subtitle']]
|
||||
}
|
||||
|
||||
def test_collect_all_resources(self):
|
||||
res = coursera_dl.find_resources_to_get(self.sample_bag, 'all', None)
|
||||
|
||||
self.assertEqual([('mp4', 'h://url1/lc1.mp4', 'video'),
|
||||
('pdf', 'h://url2/lc2.pdf', 'slides'),
|
||||
('txt', 'h://url3/lc3.txt', 'subtitle')], sorted(res))
|
||||
|
||||
def test_collect_only_pdfs(self):
|
||||
res = coursera_dl.find_resources_to_get(self.sample_bag, 'pdf', None)
|
||||
|
||||
self.assertEqual([('pdf', 'h://url2/lc2.pdf', 'slides')],
|
||||
sorted(res))
|
||||
|
||||
def test_collect_with_filtering(self):
|
||||
res = coursera_dl.find_resources_to_get(self.sample_bag, 'all', 'de')
|
||||
res = sorted(res)
|
||||
|
||||
self.assertEqual([('mp4', 'h://url1/lc1.mp4', 'video'),
|
||||
('pdf', 'h://url2/lc2.pdf', 'slides')], res)
|
||||
|
||||
|
||||
class ExternalDownloaderTestCase(unittest.TestCase):
|
||||
|
|
|
|||
|
|
@ -4,15 +4,47 @@
|
|||
"""
|
||||
Test functionality of coursera module.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os.path
|
||||
import unittest
|
||||
|
||||
from six import iteritems
|
||||
from mock import patch, Mock, mock_open
|
||||
|
||||
from coursera import coursera_dl
|
||||
|
||||
|
||||
class TestJSonHandling(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.saved_get_page = coursera_dl.get_page
|
||||
self.json_path = os.path.join(os.path.dirname(__file__), "fixtures", "json")
|
||||
|
||||
def tearDown(self):
|
||||
coursera_dl.get_page = self.saved_get_page
|
||||
|
||||
def test_that_should_not_dl_if_file_exist(self):
|
||||
coursera_dl.get_page = Mock()
|
||||
coursera_dl.download_about(object(), "matrix-002", self.json_path)
|
||||
self.assertFalse(coursera_dl.get_page.called)
|
||||
|
||||
def test_that_we_parse_and_write_json_correctly(self):
|
||||
|
||||
raw_data = open(os.path.join(os.path.dirname(__file__), "fixtures", "json", "unprocessed.json")).read()
|
||||
coursera_dl.get_page = lambda x, y: raw_data
|
||||
open_mock = mock_open()
|
||||
|
||||
with patch('coursera.coursera_dl.open', open_mock, create=True):
|
||||
|
||||
coursera_dl.download_about(object(), "networksonline-002", self.json_path)
|
||||
|
||||
open_mock.assert_called_once_with(os.path.join(self.json_path, 'networksonline-002-about.json'), 'w')
|
||||
|
||||
data = json.loads(open_mock().write.call_args[0][0])
|
||||
|
||||
self.assertEqual(data['id'], 394)
|
||||
self.assertEqual(data['shortName'], 'networksonline')
|
||||
|
||||
|
||||
class TestSyllabusParsing(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import datetime
|
|||
import os
|
||||
import random
|
||||
import unittest
|
||||
from time import time
|
||||
|
||||
import requests
|
||||
import six
|
||||
|
|
@ -87,6 +88,30 @@ class UtilsTestCase(unittest.TestCase):
|
|||
url = " www.coursera.org "
|
||||
self.assertEquals(utils.fix_url(url), 'http://www.coursera.org')
|
||||
|
||||
def test_format_combine_resource_works_correctly(self):
|
||||
rv = coursera_dl.format_combine_number_resource( 5, 4, "Moving_the_furniture", 'The_Basics', "mp4")
|
||||
self.assertEqual('05_04_Moving_the_furniture_The_Basics.mp4', rv)
|
||||
|
||||
def test_format_combine_resource_works_correctly_without_title(self):
|
||||
rv = coursera_dl.format_combine_number_resource( 5, 1, "Introduction", '', "mp4")
|
||||
self.assertEqual('05_01_Introduction.mp4', rv)
|
||||
|
||||
def test_format_resource_works_correctly(self):
|
||||
rv = coursera_dl.format_resource( 2, "Washing", "Dishes", "mp9")
|
||||
self.assertEqual('02_Washing_Dishes.mp9', rv)
|
||||
|
||||
def test_format_resource_works_correctly_without_title(self):
|
||||
rv = coursera_dl.format_resource( 1, "Introduction", '', "mp2")
|
||||
self.assertEqual('01_Introduction.mp2', rv)
|
||||
|
||||
def test_format_section_works_correctly(self):
|
||||
rv = coursera_dl.format_section( 9, 'bob', 'WEAVING', False )
|
||||
self.assertEqual('09_bob', rv)
|
||||
|
||||
def test_format_section_works_correctly_with_verbose(self):
|
||||
rv = coursera_dl.format_section( 9, 'bill', 'WEAVING', True )
|
||||
self.assertEqual('WEAVING_09_bill', rv)
|
||||
|
||||
def test_fix_url_doesnt_alters_empty_url(self):
|
||||
url = None
|
||||
self.assertEquals(utils.fix_url(url), None)
|
||||
|
|
@ -108,6 +133,33 @@ class UtilsTestCase(unittest.TestCase):
|
|||
ts = coursera_dl.total_seconds(datetime.timedelta(days=30))
|
||||
self.assertEquals(ts, 2592000)
|
||||
|
||||
def test_is_course_complete_should_give_false_if_there_was_recent_update(self):
|
||||
|
||||
delta = coursera_dl.total_seconds(datetime.timedelta(days=29))
|
||||
tm = time() - delta
|
||||
|
||||
rv = coursera_dl.is_course_complete(tm)
|
||||
self.assertFalse(rv)
|
||||
|
||||
def test_is_course_complete_should_give_true_if_there_was_no_recent_update(self):
|
||||
|
||||
delta = coursera_dl.total_seconds(datetime.timedelta(days=31))
|
||||
tm = time() - delta
|
||||
|
||||
rv = coursera_dl.is_course_complete(tm)
|
||||
self.assertTrue(rv)
|
||||
|
||||
def test_correct_formatting_of_class_URL(self):
|
||||
|
||||
url = coursera_dl.get_syllabus_url('bob', False)
|
||||
self.assertEqual('https://class.coursera.org/bob/lecture/index', url)
|
||||
|
||||
def test_correct_formatting_of_class_with_preview_URL(self):
|
||||
|
||||
url = coursera_dl.get_syllabus_url('bill', True)
|
||||
self.assertEqual('https://class.coursera.org/bill/lecture/preview', url)
|
||||
|
||||
|
||||
def test_parse_args(self):
|
||||
args = coursera_dl.parseArgs(['-u', 'bob', '-p', 'bill', 'posa-001'])
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue