Skip to content

Instantly share code, notes, and snippets.

@sadmicrowave
Created November 1, 2018 20:38
Show Gist options
  • Save sadmicrowave/d4fbefc124eb69027d7a3131526e8c06 to your computer and use it in GitHub Desktop.
Save sadmicrowave/d4fbefc124eb69027d7a3131526e8c06 to your computer and use it in GitHub Desktop.
Challenge: 11.1.2018 - First Factorial
#!/usr/local/bin/python3
# ---------------------------------- MODULE IMPORTS ---------------------------------------- #
import sys, cProfile
from functools import reduce
# --------------------------------- CHALLENGE CONTEXT -------------------------------------- #
# Using the Python language, have the function FirstFactorial(num) take the num parameter being
# passed and return the factorial of it (e.g. if num = 4, return (4 * 3 * 2 * 1)). For the test
# cases, the range will be between 1 and 18 and the input will always be an integer.
#
# Sample Test Cases
# Input:4
# Output:24
#
# Input:8
# Output:40320
#
# --------------------------------- PROCESS WIREFRAME -------------------------------------- #
#
# 1. Need to ensure the input value is an integer
# 2. Create list of all numbers from input num to 1
# 3. Need to multiply each number against the other
# 4. Return the computed value
#
# --------------------------------- ENVIRONMENT SETUP -------------------------------------- #
class InvalidInputException ( Exception ) :
""" Custom exception class which extends BaseException used to throw properly named exception
upon encountering invalid input data.
"""
pass
# --------------------------------- PROPOSED SOLUTION -------------------------------------- #
class FirstFactorial :
""" Class designed to return the product of a Factorial mathmatics operation. This class does
not return an instance when instantiated, rather the product of the mathmatics operation."""
def __new__ ( cls, num, profile ) :
""" Used in place of __init__ to make the class uninstantiable and return a value rather
than an instance.
:param: num (int) / integer to use to calculate factorial product
:param: profile (bool) / used to determine if profiler should be executed for input number
:throws: InvalidInputException (exception) / Custom exception class to handle Input errors
:return (int): / product of factorial calculation
"""
# 1. Ensure input number is an integer by attempting to cast value to int
# 1a. To accomplish, we attempt to cast the input value to int() type and catch the TypeError/ValueError
# if the conversion cannot happen because the value type is incorrect
# 2. Create a list of all numbers from n to 1 to then be multiplied against each other
# using list comprehension and range loop in reverse order from highest number to smallest.
# 3. Use reduce to walk the list of integers and multiply each against the next.
# 3a. Here, reduce will call the registered lambda function for each element in the list.
# Reduce will execute lambda for the first 2 elements in the list, then the product is
# multiplied by the next element in the list, and so-on, until the list ends.
try :
if profile :
cProfile.run( 'FirstFactorial( %s )' % num )
num = int( num )
return reduce( lambda x, y: x * y, [n for n in range(num, 0, -1)] )
except ( TypeError, ValueError ) :
raise InvalidInputException ( "Input must be an integer, greater than 0!" )
# --------------------------------- ALTERNATE SOLUTIONS ------------------------------------ #
# --------------------------------- MAIN EXECUTION BLOCK ----------------------------------- #
if __name__ == '__main__' :
# Only run the profiler if the command line switch is passed with the call of the script
# E.g.: python FirstFactorial.py -p
profile = True if len( sys.argv ) > 1 and sys.argv[1] == '-p' else False
# keep this function call here, where "input()" is user input
print( FirstFactorial( input(), profile ) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment