mirror of
https://github.com/fschmnn/duodecimal.git
synced 2024-06-14 05:29:28 +00:00
2019.03.09 - initial commit
This commit is contained in:
commit
74d442439c
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.ipynb_checkpoints/
|
||||||
|
__pycache__/
|
151
duodecimal.py
Normal file
151
duodecimal.py
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
class duo:
|
||||||
|
''' class to represent duodecimal numbers
|
||||||
|
|
||||||
|
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , X , E
|
||||||
|
|
||||||
|
Input:
|
||||||
|
------
|
||||||
|
either string (base12) or float/int (base10)
|
||||||
|
|
||||||
|
http://www.dozenal.org/drupal/sites_bck/default/files/DSA-ConversionRules_0.pdf
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self,number):
|
||||||
|
''' determine type of input and convert to decimal/duodecimal '''
|
||||||
|
|
||||||
|
self.duo_digits = {0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5',
|
||||||
|
6: '6', 7: '7', 8: '8', 9: '9', 10: 'X', 11: 'E'}
|
||||||
|
self.dec_digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5,
|
||||||
|
'6': 6, '7': 7, '8': 8, '9': 9, 'E': 11, 'X': 10}
|
||||||
|
self.base = 12
|
||||||
|
|
||||||
|
if type(number) == int or type(number) == float:
|
||||||
|
self.decimal = number
|
||||||
|
self.duodecimal = self.dec_to_duo(number)
|
||||||
|
|
||||||
|
elif type(number) == str:
|
||||||
|
self.decimal = self.duo_to_dec(number)
|
||||||
|
self.duodecimal = number.rstrip('0')
|
||||||
|
else:
|
||||||
|
raise TypeError('unkown type')
|
||||||
|
|
||||||
|
def dec_to_duo(self,number):
|
||||||
|
''' convert decimal float/int to duodecimal string '''
|
||||||
|
|
||||||
|
# handle negative numbers
|
||||||
|
if number <0:
|
||||||
|
number = abs(number)
|
||||||
|
sign = '-'
|
||||||
|
else:
|
||||||
|
sign = ''
|
||||||
|
integer, fractional = divmod(number,1)
|
||||||
|
|
||||||
|
out = []
|
||||||
|
quotient = integer
|
||||||
|
while quotient != 0:
|
||||||
|
quotient, remainder = divmod(quotient,self.base)
|
||||||
|
out.insert(0,remainder)
|
||||||
|
integer = ''.join([self.duo_digits[dig] for dig in out])
|
||||||
|
|
||||||
|
if fractional:
|
||||||
|
out = []
|
||||||
|
remainder = fractional
|
||||||
|
for i in range(len(str(fractional).split('.')[1])+1):
|
||||||
|
quotient, remainder = divmod(remainder*self.base,1)
|
||||||
|
out.append(quotient)
|
||||||
|
if remainder > 0.5:
|
||||||
|
out.append(1)
|
||||||
|
decimal = '.' + ''.join([self.duo_digits[dig] for dig in out])
|
||||||
|
else:
|
||||||
|
decimal = ''
|
||||||
|
|
||||||
|
return sign + integer + decimal.rstrip('0')
|
||||||
|
|
||||||
|
def duo_to_dec(self,string):
|
||||||
|
''' convert duodecimal string to decimal float/int '''
|
||||||
|
|
||||||
|
# handle negative numbers
|
||||||
|
if string.startswith('-'):
|
||||||
|
string = string[1:]
|
||||||
|
sign = -1
|
||||||
|
else:
|
||||||
|
sign = 1
|
||||||
|
|
||||||
|
if set(string) > set('123456789XE'):
|
||||||
|
invalid = set(string) - set('123456789XE')
|
||||||
|
raise ValueError('invalid character'.format(invalid))
|
||||||
|
|
||||||
|
if '.' in string:
|
||||||
|
integer, fractional = string.split('.')
|
||||||
|
else:
|
||||||
|
integer, fractional = string, ''
|
||||||
|
|
||||||
|
out = 0
|
||||||
|
for power, digit in enumerate(integer[::-1]):
|
||||||
|
out += self.dec_digits[digit] * self.base**power
|
||||||
|
for power, digit in enumerate(str(fractional),1):
|
||||||
|
out += self.dec_digits[digit] * self.base**(-power)
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
def __add__(self,other):
|
||||||
|
'''add two duodecimal numbers'''
|
||||||
|
|
||||||
|
if isinstance(other, duo):
|
||||||
|
result = self.decimal + other.decimal
|
||||||
|
elif type(other) == int or type(other) == float:
|
||||||
|
result = self.decimal + other
|
||||||
|
elif type(other) == str:
|
||||||
|
result = self.decimal + self.duo_to_dec(other)
|
||||||
|
else:
|
||||||
|
raise TypeError('unkown type')
|
||||||
|
return duo(result)
|
||||||
|
|
||||||
|
def __sub__(self,other):
|
||||||
|
''' subtract two duodecimal numbers '''
|
||||||
|
|
||||||
|
if isinstance(other, duo):
|
||||||
|
result = self.decimal - other.decimal
|
||||||
|
elif type(other) == int or type(other) == float:
|
||||||
|
result = self.decimal - other
|
||||||
|
elif type(other) == str:
|
||||||
|
result = self.decimal - self.duo_to_dec(other)
|
||||||
|
else:
|
||||||
|
raise TypeError('unkown type')
|
||||||
|
return duo(result)
|
||||||
|
|
||||||
|
def __mul__(self,other):
|
||||||
|
''' multiply two duodecimal numbers '''
|
||||||
|
|
||||||
|
if isinstance(other, duo):
|
||||||
|
result = self.decimal * other.decimal
|
||||||
|
elif type(other) == int or type(other) == float:
|
||||||
|
result = self.decimal * other
|
||||||
|
elif type(other) == str:
|
||||||
|
result = self.decimal * self.duo_to_dec(other)
|
||||||
|
else:
|
||||||
|
raise TypeError('unkown type')
|
||||||
|
return duo(result)
|
||||||
|
|
||||||
|
def __truediv__(self,other):
|
||||||
|
''' divide two duodecimal numbers '''
|
||||||
|
|
||||||
|
if isinstance(other, duo):
|
||||||
|
result = self.decimal / other.decimal
|
||||||
|
elif type(other) == int or type(other) == float:
|
||||||
|
result = self.decimal / other
|
||||||
|
elif type(other) == str:
|
||||||
|
result = self.decimal / self.duo_to_dec(other)
|
||||||
|
else:
|
||||||
|
raise TypeError('unkown type')
|
||||||
|
return duo(result)
|
||||||
|
|
||||||
|
def dec(self):
|
||||||
|
''' return the decimal representation '''
|
||||||
|
return self.decimal
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return self.duodecimal[:7].rstrip('0') + '(base12)'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.duodecimal
|
213
example_usage.ipynb
Normal file
213
example_usage.ipynb
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Example usage of the duo class\n",
|
||||||
|
"\n",
|
||||||
|
"## Basic operations"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"metadata": {
|
||||||
|
"collapsed": true
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from duodecimal import duo"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"36(base12)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 2,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"duo(42)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"24(base12)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"duo('24')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 4,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"5X(base12)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 4,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"a = duo(42)\n",
|
||||||
|
"b = duo(28)\n",
|
||||||
|
"\n",
|
||||||
|
"a + b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 5,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"12(base12)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 5,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"a - b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 6,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"1(base12)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 6,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"duo(3) * 4"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"3.4(base12)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 7,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"duo(10) / '3'"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Create a multiplication table"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 8,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"\t1 \t2 \t3 \t4 \t5 \t6 \t7 \t8 \t9 \t10 \t11 \t12\n",
|
||||||
|
"---------------------------------------------------------------------------------------------------\n",
|
||||||
|
" 1| \t1 \t2 \t3 \t4 \t5 \t6 \t7 \t8 \t9 \tX \tE \t10\n",
|
||||||
|
" 2| \t2 \t4 \t6 \t8 \tX \t10 \t12 \t14 \t16 \t18 \t1X \t20\n",
|
||||||
|
" 3| \t3 \t6 \t9 \t10 \t13 \t16 \t19 \t20 \t23 \t26 \t29 \t30\n",
|
||||||
|
" 4| \t4 \t8 \t10 \t14 \t18 \t20 \t24 \t28 \t30 \t34 \t38 \t40\n",
|
||||||
|
" 5| \t5 \tX \t13 \t18 \t21 \t26 \t2E \t34 \t39 \t42 \t47 \t50\n",
|
||||||
|
" 6| \t6 \t10 \t16 \t20 \t26 \t30 \t36 \t40 \t46 \t50 \t56 \t60\n",
|
||||||
|
" 7| \t7 \t12 \t19 \t24 \t2E \t36 \t41 \t48 \t53 \t5X \t65 \t70\n",
|
||||||
|
" 8| \t8 \t14 \t20 \t28 \t34 \t40 \t48 \t54 \t60 \t68 \t74 \t80\n",
|
||||||
|
" 9| \t9 \t16 \t23 \t30 \t39 \t46 \t53 \t60 \t69 \t76 \t83 \t90\n",
|
||||||
|
"10| \tX \t18 \t26 \t34 \t42 \t50 \t5X \t68 \t76 \t84 \t92 \tX0\n",
|
||||||
|
"11| \tE \t1X \t29 \t38 \t47 \t56 \t65 \t74 \t83 \t92 \tX1 \tE0\n",
|
||||||
|
"12| \t10 \t20 \t30 \t40 \t50 \t60 \t70 \t80 \t90 \tX0 \tE0 \t100\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"multiplication_table = []\n",
|
||||||
|
"for i in range(1,13):\n",
|
||||||
|
" row = ['{:>2}|'.format(i)]\n",
|
||||||
|
" for j in range(1,13):\n",
|
||||||
|
" row.append(duo(i*j).__str__())\n",
|
||||||
|
" multiplication_table.append(row)\n",
|
||||||
|
"print('\\t'+' \\t'.join(map(str,range(1,13)))+ '\\n'+99*'-')\n",
|
||||||
|
"for row in multiplication_table:\n",
|
||||||
|
" print(' \\t'.join(row))"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user