diff --git a/_episodes/02-functional.md b/_episodes/02-functional.md index 6ac6806..c69b61f 100644 --- a/_episodes/02-functional.md +++ b/_episodes/02-functional.md @@ -367,7 +367,7 @@ print(reduce((lambda a, b: a + b), l)) > ~~~ > {: .output} > -> > # Solution +> > ## Solution > > > > ~~~ > > from functools import reduce @@ -398,7 +398,7 @@ print(reduce((lambda a, b: a + b), l)) > ~~~ > {: .output} > -> > # Solution +> > ## Solution > > > > ~~~ > > from functools import reduce diff --git a/_episodes/04-functional-python.md b/_episodes/04-functional-python.md index d505cc5..558f258 100644 --- a/_episodes/04-functional-python.md +++ b/_episodes/04-functional-python.md @@ -247,45 +247,57 @@ for i in count_to_n(5): ~~~ {: .output} -Counting papers from academics - -Sorting papers by title, day - -Needs to end day with 2d array of papers published per person per day - run a simulation of people publishing on random days - -~~~ -class Person: - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name - -class Academic(Person): - def __init__(self, name): - super().__init__(name) - self.papers = [] - self.staff = [] - - def write_paper(title, day): - new_paper = Paper(title, day) - - self.papers.append(new_paper) - return new_paper - - def add_staff(academic): - if academic not in self.staff: - self.staff.append(academic) - -academics = [Academic(name) for name in ['Alice', 'Bob', 'Carol', 'David']] -alice = academics[0] -bob = academics[1] -alice.add_staff(bob) - - -~~~ -{: .language-python} - +> ## Extending Academic Model +> +> Optional example - doesn't need to be included. +> Counting papers from academics. +> +> ~~~ +> class Person: +> def __init__(self, name): +> self.name = name +> +> def __str__(self): +> return self.name +> +> class Academic(Person): +> def __init__(self, name): +> super().__init__(name) +> self.papers = [] +> self.staff = [] +> +> def write_paper(title): +> new_paper = Paper(title) +> +> self.papers.append(new_paper) +> return new_paper +> +> def add_staff(academic): +> if academic not in self.staff: +> self.staff.append(academic) +> +> @property +> def all_papers(self): +> papers = self.papers +> for staff in self.staff: +> papers = papers + staff.all_papers +> +> return papers +> +> +> academics = [Academic(name) for name in ['Alice', 'Bob', 'Carol', 'David']] +> alice = academics[0] +> bob = academics[1] +> alice.add_staff(bob) +> +> alice.write_paper('A science paper') +> bob.write_paper('Another science paper') +> +> print(alice.all_papers) +> +> ~~~ +> {: .language-python} +{: .callout} ## Decorators Function that accepts a function and returns a (different) function @@ -312,5 +324,159 @@ World! ~~~ {: .output} +> ## Sum of Squares (Again) +> +> Instead of using the `map` and `filter` functions, write a sum of squares function using comprehensions. +> +> You may find the `sum` function useful - it sums all items in an iterable collection. +> +> ~~~ +> def sum_of_squares(l): +> # Your code here +> +> print(sum_of_squares([0])) +> print(sum_of_squares([1])) +> print(sum_of_squares([1, 2, 3])) +> print(sum_of_squares([-1])) +> print(sum_of_squares([-1, -2, -3])) +> ~~~ +> {: .language-python} +> +> ~~~ +> 0 +> 1 +> 14 +> 1 +> 14 +> ~~~ +> {: .output} +> +> > ## Solution +> > +> > ~~~ +> > def sum_of_squares(l): +> > squares = [x * x for x in l] +> > return sum(squares) +> > ~~~ +> > {: .language-python} +> > +> {: .solution} +> +> Now let's assume we're reading in these numbers from an input file, so they arrive as a list of strings. +> Modify your function so that it passes the following tests: +> +> ~~~ +> print(sum_of_squares(['1', '2', '3'])) +> print(sum_of_squares(['-1', '-2', '-3'])) +> ~~~ +> {: .language-python} +> +> ~~~ +> 14 +> 14 +> ~~~ +> {: .output} +> +> > ## Solution +> > +> > ~~~ +> > def sum_of_squares(l): +> > integers = [int(x) for x in l] +> > squares = [x * x for x in integers] +> > return sum(squares) +> > ~~~ +> > {: .language-python} +> > +> > Or, using only one comprehension: +> > +> > ~~~ +> > def sum_of_squares(l): +> > return sum([int(x) * int(x) for x in l]) +> > ~~~ +> > {: .language-python} +> > +> {: .solution} +> +> Finally, like comments in Python, we'd like it to be possible for users to comment out numbers in the input file the give to our program. +> Extend your function so that the following tests pass (don't worry about passing the first set of tests with lists of integers): +> +> ~~~ +> print(sum_of_squares(['1', '2', '3'])) +> print(sum_of_squares(['-1', '-2', '-3'])) +> print(sum_of_squares(['1', '2', '#100', '3'])) +> ~~~ +> {: .language-python} +> +> ~~~ +> 14 +> 14 +> 14 +> ~~~ +> {: .output} +> +> > ## Solution +> > +> > ~~~ +> > def sum_of_squares(l): +> > not_comments = [x for x in l if x[0] != '#'] +> > integers = [int(x) for x in not_comments] +> > squares = [x * x for x in integers] +> > return sum(squares) +> > ~~~ +> > {: .language-python} +> > +> > Or, in one comprehension: +> > +> > ~~~ +> > def sum_of_squares(l): +> > return sum([int(x) * int(x) for x in l if x[0] != '#']) +> > ~~~ +> > {: .language-python} +> {: .solution} +> +{: .challenge} + +> ## Dictionary of Squares +> +> Define a function `dict_of_squares` which takes an integer and returns a dictionary whose keys `i` are the integers from 1 to N (inclusive) and whose values are lists of square numbers up to `i` squared. +> +> For example: +> +> ~~~ +> def dict_of_squares(n): +> # your code here +> +> print(dict_of_squares(3)) +> ~~~ +> {: .language-python} +> +> ~~~ +> {1: [1], 2: [1, 4], 3: [1, 4, 9]} +> ~~~ +> {: .output} +> +> > ## Solution +> > ~~~ +> > def dict_of_squares(n): +> > return {i: [j * j for j in range(1, i + 1)] for i in range(1, n + 1)} +> > ~~~ +> > {: .language-python} +> > +> > To improve readability, you may wish to format it differently - such as: +> > +> > ~~~ +> > def dict_of_squares(n): +> > return { +> > i: [ +> > j * j for j in range(1, i + 1) +> > ] for i in range(1, n + 1) +> > } +> > ~~~ +> > {: .language-python} +> > +> {: .solution} +> +{: .challenge} + {% include links.md %} diff --git a/setup.md b/setup.md index b8c5032..b56d1fb 100644 --- a/setup.md +++ b/setup.md @@ -1,7 +1,20 @@ --- title: Setup --- -FIXME +As yesterday, we need to download the training materials from the GitHub code repository online. Go to `https://github.com/sabs-r3/module01_se_day2` in a browser and select the green `Clone or download` button, and then select `Download ZIP`. This will download all the files within a single archive file. After it's finished downloading, we need to extract all files from the archive. Find where the file has been downloaded to, then start a terminal, and assuming the file has downloaded to e.g. `/home/sabs-r3/Downloads`, do the following within the shell: + +~~~ +cd ~ +unzip /home/sabs-r3/Downloads/module01_se_day2-gh-pages.zip +~~~ +{: .language-bash} + +This will unpack the archive in your home directory, within a subdirectory called `module01_se_day2-gh-pages`. Change to the `code` directory within that new directory: + +~~~ +cd module01_se_day2-gh-pages/code +~~~ +{: .language-bash} {% include links.md %}