Skip to content

Instantly share code, notes, and snippets.

@blueset

blueset/README.md

Last active Aug 22, 2016
Embed
What would you like to do?
UniMelb COMP10001 2016S2 Practice Project: My Solution

Here I'm posting my solutions to the Practice Project for the COMP10001 Foundation of Computing course in the University of Melbourne in Semester 2, 2016.

NOTICE

The solution below is just my solution. IT IS NOT:

  • A sample answer from any lecturer, tutor, or any teaching staff.
  • A marking scheme used for any of the actual assessments
  • A perfect solution for anyone to take as a template for your project
  • A reason for you to give up on trying your practice project

I advice you to try on your own first before you read this solution.
All the following solutions has been put to test with the Grok System, but it might NOT be fulfilling the code quality requirement of the marking scheme. (Although I think it should, XP)

Again, the license:

Copyright (c) 2016 Eana Hufwe

Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software and associated documentation files (the "Software"), 
to deal in the Software without restriction, including without limitation 
the rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or sell copies of the Software, and to permit persons to whom the 
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included 
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
IN THE SOFTWARE.

Techinical details

  1. All source files in this solution follows PEP8 (Python Enhancement Proposals 8: Style Guide for Python Code, the de facto style guide for all Python users) as far as possible.
  2. All docstrings follows Google's Python Style Guide as far as possible.
  3. All file-level docstrings repeats the question in Markdown, extended with inline LaTeX support.

File Structure

  1. Shellbang, for direct refer to the script in most shell.
  2. Encoding declairation, although not necessary in this context.
  3. File-level docstring, repeats the question.
  4. Import libraries, if necessary.
  5. File meta-information declaration, including author, copyright, license, version, and contact.
  6. Define functions
  7. Function docstring, state briefly what the function does, examples, argument(s), and return value(s).
  8. Code, Commenting on each necessary step

What to notice with PEP8?

Again, this is not a guide or something. Just sharing my solution. Please don't take it as a guidebook. If you really want one, please consult PEP8.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""Kinda Fermat
Write a function `kinda_fermat(a, b, c)` that takes three arguments a, b and c,
each of which is a positive int, and tests whether the equality $a^n+b^n=c^n$
holds for each $n \in {2,3,…,10}$ (i.e. all integers from 2 to 10 inclusive).
If there is a value of n for which the equality holds, your function should
return the lowest such value (as an int). Your function should return False if
the equality does not hold for any value of n in the given range.
"""
__author__ = "Eana Hufwe"
__copyright__ = "Copyright 2016, Eana Hufwe, 1A23 Studio"
__license__ = "MIT License"
__version__ = "1"
__email__ = "ilove@1a23.com"
def kinda_fermat(a, b, c):
"""Kinda Fermat
Checks the equality $a^n+b^n=c^n$ for all integers between 2 and 10
inclusive.
Example:
>>> kinda_fermat(3, 4, 5)
2
>>> kinda_fermat(1, 2, 3)
False
Args:
a (int): Varible a
b (int): Varible b
c (int): Varible c
Returns:
int|bool: The smallest n that satisfy the equation, or `False` if no
n in the range satisfies.
"""
# Check for each value from 2 to 10
for n in range(2, 11):
# Check if the value n satisfies the equation
if a ** n + b ** n == c ** n:
# Return the smallest n and end the program
return n
# Returns `False` if there is no n in the range satisfies the equation
return False
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""Least Vowel Words
Write a function `least_vowel_words(text)` that takes one argument text
containing a block of `text` in the form of a `str`, and returns a list of
unique word(s) with the lowest "vowel proportion" as a `list`. The vowel
proportion is defined as the proportion of letters in the word which are
vowels (e.g. the vowel proportion of "life" is $\frac{2}{4} = 0.5$). The
returned list will have multiple elements if and only if there is a tie for
lowest vowel proportion, and in this case, the elements should be ordered as
they (first) appear in `text`.
"Words" should be assumed to be separated by whitespace (spaces, tabs or
newlines). In all cases, all "words" should be converted to lower case and
any punctuation should be stripped from the (right) end of the word, in the
form of the following punctuation marks **ONLY**: commas (","), fullstops
("."), colons (":"), semi-colons (";"), exclamation marks ("!"), question
marks ("?"), single quotes ("'"), double quotes ('"'), and hyphens ("-").
"""
import re
__author__ = "Eana Hufwe"
__copyright__ = "Copyright 2016, Eana Hufwe, 1A23 Studio"
__license__ = "MIT License"
__version__ = "1"
__email__ = "ilove@1a23.com"
def least_vowel_words(text):
"""Least Vowel Words
Strip out words and convert it to lower case. Then fit words with least
vowel ratio to a list and return it.
Example:
>>> least_vowel_words("the rhythm of life")
['rhythm']
>>> least_vowel_words("The quality of mercy is not strain'd " +
... "... mercy Percy.")
['mercy', 'percy']
Args:
text (str): String to be processed.
Returns:
list of str: list of words has the least vowel ratio
"""
# Turn the string into lower-case
lower = text.lower()
# Break up the chain of words into different words.
words = re.findall(r"\s?(\S*[^,.:;!?'\s-])[,.:;!?'" + r'"' + r"-]*\s?", lower)
# Make space for the final results
min_rate = 1
result = []
# traverse through all words
for word in words:
# Count all vowels
vowel_count = len([i for i in word if i in 'aeiou'])
# Calculate the rate
rate = vowel_count / len(word)
if min_rate > rate:
# Update if the rate is lower
min_rate = rate
result = [word]
elif min_rate == rate and word not in result:
# Append if 2 words has the same rate and no duplicate is found
result += [word]
return result
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""Symmetric Words
Write a function `symmetric_words(wlist)` that takes a single argument `wlist`
containing a list of words each in the form of an all-lowercase non-empty
`str`, and returns a sorted `list` of "symmetric" words. A symmetric word
is defined as a word where for all values $i$, the letter $i$ positions
from the start of the word and the letter $i$ positions from the end of the
word are equidistant from the respective ends of the alphabet.
For example, `bevy` is a symmetric word as: `b` (1 position from the start of
the word) is the second letter of the alphabet and `y` (1 position from the
end of the word) is the second-last letter of the alphabet; and `e` (2
positions from the start of the word) is the fifth letter of the alphabet
and `v` (2 positions from the end of the word) is the fifth-last letter of
the alphabet.
"""
__author__ = "Eana Hufwe"
__copyright__ = "Copyright 2016, Eana Hufwe, 1A23 Studio"
__license__ = "MIT License"
__version__ = "1"
__email__ = "ilove@1a23.com"
def flip_word(word):
"""Flip a string of lower-case letters in alphabetical order, so that
"a" becomes "z", "b" becomes "y", etc.
Args:
word (str): Word to be filpped with only lower-case letters.
Returns:
str: Flipped word.
"""
# Convert letters in the word to a list of integers showing their order
letter_id = [ord(i) - ord('a') for i in word]
# Flip those numbers by substracting by 25
flipped_id = [25 - i for i in letter_id]
# Convert flipped numbers back to a list of characters
flipped_letters = [chr(ord('a') + i) for i in flipped_id]
# Join the letters into a string and return it
return "".join(flipped_letters)
def symmetric_words(wlist):
"""Symmetric Words
Return a list of words in ASCII order that are considered as
symmetric words.
A symmetric word is defined as a word where for all values i, the letter
i positions from the start of the word and the letter i positions from
the end of the word are equidistant from the respective ends of the
alphabet.
Example:
>>> symmetric_words(["boy", "dog", "bevy", "bully"])
['bevy']
>>> symmetric_words(["neither", "a", "borrower", "nor", "a",
... "lender", "be"])
[]
Args:
wlist (list of str): List of words with only lowercase letters
Returns:
list: The sorted list of words that are symmetric.
"""
# Create a list container for results
result = []
# Traversing each word in `wlist`
for word in wlist:
# Flip the reversed word with the function `flip_word`.
flipped_word = flip_word(word[::-1])
# Check if the first half is identical to the flipped second half
if word == flipped_word:
# Include the original word in the result if so.
result.append(word)
# Sort the result
result.sort()
return result
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""Unique Long Words
Write a function `unique_long_words(wlist, wlen)` that takes two arguments:
1. `wlist` containing a list of words (each in the form of an all-lowercase
`str`)
2. wlen which specifies a minimum word length as an `int`
The function should return the number of unique words contained in `wlist`
which are of length `wlen` or greater.
"""
__author__ = "Eana Hufwe"
__copyright__ = "Copyright 2016, Eana Hufwe, 1A23 Studio"
__license__ = "MIT License"
__version__ = "1"
__email__ = "ilove@1a23.com"
def unique_long_words(wlist, wlen):
"""Unique Long Words
Returns the number of unique words with length larger or equals to
`wlen`.
Example:
>>> unique_long_words(["the", "quick", "brown", "fox", "jumps", "over",
... "the", "lazy", "dog"], 3)
8
>>> unique_long_words(["how", "much", "wood", "could", "a", "wood",
... "chuck", "chuck"], 2)
5
Args:
wlist (list of str): List of words with only lowercase letters
wlen (int): The minimum length of words to be selected
Returns:
int: The number of words that meets the requirement.
"""
# Filter out long words with a list comprehension
long_words = [i for i in wlist if len(i) >= wlen]
# Remove duplicate words by converting it to a `set`
unique_words = set(long_words)
# return the number of words that meet the requirement.
return len(unique_words)

Bonus: What will those programs like if I'd like to do it in my style (i.e. short and not so sweet)

Don't take it so serious.

kinda-fermat.py

def kinda_fermat(a, b, c):
    for n in range(2, 11):
        if a ** n + b ** n == c ** n:
            return n
    return False

least-vowel-words.py

import re
def least_vowel_words(text):
    words = re.findall(r"\s?(\S*[^,.:;!?'\s-])[,.:;!?'" + r'"' + r"-]*\s?", text.lower)
    min_rate = 1
    result = []
    for word in words:
        rate = len([i for i in word if i in 'aeiou']) / len(word)
        if min_rate > rate:
            min_rate = rate
            result = [word]
        elif min_rate == rate and word not in result:
            result += [word]
    return result

symmetric-words.py

symmetric_words = lambda wlist: sorted([i for i in wlist if word == "".join([chr(ord('a') + 25 - (ord(i) - ord('a'))) for i in word[::-1]])])

unique-long-words.py

unique_long_words = lambda wlist, wlen: len(set([i for i in wlist if len(i) >= wlen]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment