I'm trying to make a function that takes in a number in base 10 and can be changed to any base from 2 though 9. I'm trying to only use the math module and just some simple math.
My code involves strings and I would like to eliminate them, and instead have the function do some math instead of using the numbers in a string. Also I'm trying to make the output integers.
def conver(n,b):
digits = ('0123456789')
ans = ""
while n > 0:
ans = digits[n%b] + ans
n //= b
return ans
For example the user could in put in the values (14,2) and get the output 1110
a simple implementation which can "convert" up to base 9 is as follows:
def conver(n,b):
a = 0
i = 0
while n:
n,r = divmod(n,b)
a += 10**i * r
i += 1
return a
note that n,r = divmod(n,b) could be r = n % b; n //= b
Note that the number you're getting is an integer all right (as a type), but it makes no sense using it as such because the base is wrong: Ex: 1110 is not really 1110. So it's not really different than a string...
Well, that's just for the sake of the exercise.
Related
This function takes in any base-10 integer and returns the string representation of that number in its specified base-32 form:
def encodeN(n,N,D="0123456789qwertyuiopasdfghjklzxc"):
return (encodeN(n//N,N)+D[n%N]).lstrip("0") if n>0 else "0"
Example:
print (encodeN(16002,32))
Output:
ya2
But I have a problem with writing a decoding function from base-32 back to base-10. How can I write it? Can I enter custom nonstandard characters to extend the base-n?
You could cheat:
tmap = str.maketrans('qwertyuiopasdfghjklzxc', 'abcdefghijklmnopqrstuv')
result = int(inputvalue.translate(tmap), 32)
Demo:
>>> tmap = str.maketrans('qwertyuiopasdfghjklzxc', 'abcdefghijklmnopqrstuv')
>>> inputvalue = 'ya2'
>>> int(inputvalue.translate(tmap), 32)
16002
int() is perfectly capable of translating arbitrary bases back to integer values; all you need to do is use the standard progression of letters. The str.translate() call above maps your custom progression to the standard.
Otherwise, take each character from your input string, starting at the left, map that to an integer from your character map, and multiply by the base N each time:
def decodeN(n, N, D={c: i for i, c in enumerate("0123456789qwertyuiopasdfghjklzxc")}):
result = 0
for c in n:
result = (result * N) + D[c]
return result
This is the slower option; str.translate() and int() both use optimised C code to do their jobs, and will always be faster than a pure-python approach.
Translating that to a recursive version to match your encodeN() implementation:
def decodeN(n, N, D={c: i for i, c in enumerate("0123456789qwertyuiopasdfghjklzxc")}):
return decodeN(n[:-1], N) * N + D[n[-1]] if n else 0
With the same recursive structure, you could write:
def encodeN(n,N,D="0123456789qwertyuiopasdfghjklzxc"):
return (encodeN(n//N,N)+D[n%N]).lstrip("0") if n>0 else "0"
def decodeN(n,N,D="0123456789qwertyuiopasdfghjklzxc"):
return decodeN(n[:-1],N) * N + D.index(n[-1]) if n else 0
It seems to work fine:
print(encodeN(16002, 32))
# "ya2"
print(decodeN("ya2", 32))
# 16002
print(all(decodeN(encodeN(x, b), b) == x for b in range(2, 33) for x in range(10000)))
# True
print(all(encodeN(decodeN(str(x),32), 32) == str(x) for b in range(2, 33) for x in range(10000)))
# True
It's not very efficient though. Using a dict like MartijnPieters would be a better idea than using str.index.
>>> import string
>>> len(string.readable)
100
Judging by this you could have up to base 100 with no issues like duplicating characters or changing the encoding. But if we take out \t\n\r\x0b\x0c we get to 94.
Besides this you would have to result to some kind of custom rules, duplicating characters or prefixing them and such.
Wrote a python program that added up numbers from 1 to a given number using the Gauss equation. It worked for 100 and 10 but when I do 3 it says the sum is 4 instead of 6. The equation works out in my head, did I mess up the code?
def numberSum(num):
nim = int(num)
num = (nim/2)*(nim+1)
return num
print numberSum(raw_input())
from __future__ import division
def number_sum(num):
"""
Return sum of 1 .. num
"""
return num * (num + 1) // 2
num = int(raw_input(": "))
print(number_sum(num))
Things I changed:
number_sum should not be responsible for type-casting input; if it expects a number, you should give it some kind of number, not a string.
if num is an int, then either num or num + 1 is even, ie dividing num * (num + 1) by 2 will result in an int. This is not necessarily true of num; therefore you should divide the product by 2, not num, if you want an integer result.
in Python 2.6+, from __future__ import division makes / always return a float result and // always return an int result, consistent with Python 3.x
I suppose you are working with python2, cause by default it applies integer division like other languages. Besides, you can notice this feature in this post Integer division in python 2 and python 3.
To solve your problem you can follow the next approach:
def numberSum(num):
nim = int(num)
return ((nim * 1.0) / 2) * (nim + 1)
print numberSum(raw_input())
Is it possible to make the result from len(factors) be assigned as a variable? What I have so far is h = int(len(factors)), however i'm not sure if this actually does anything. My code below is attempting to take an integer 'r' and represent 'r' in the form (2^k)*t+1. This part of the code below is dealing with finding this product of powers of two and some other odd integer (2^k)*t.
It could be that I am going about this the wrong way, but from my research and trial and error, I have finally got this to work so far. But now more issues arise when extracting certain values.
from math import *
def executeproth():
r = input("Number to test:")
n = int(r)-1
d = 2
factors = []
while n % 2 == 0:
factors.append(d)
n = int(n/d)
h = int(len(factors))
print(n, factors, h)
# k = eval(2**h)
return factors
executeproth()
For example an input of 29 yields the following:
Number to test:29
14 [2] 1
7 [2, 2] 2
So in this instance, t=7, k=2, so we would have 29=(2^2)*7+1.
What I want to do is now take the third lines values, namely the '2', and use this for further calculations. But the commented out line # k = eval(2**h) throws the error as follows:
TypeError: eval() arg 1 must be a string, bytes or code object
So from what I can understand, the thing I am trying to evaluate is not in the correct form. I also wonder if the problem arises due to the nature of the while loop that keeps feeding values back in and creating multiples lists, as shown, and hence multiple values of h len(factors).
How would one print only the results of the 'final' iteration in the while loop? i.e. 7 [2,2] 2
Here this should fulfil your requirement,I don't think you really need to evaluate k.
Also this addresses the second part of your question too, to print the final result of the loop.
And it is as Gregory pointed out that convert explicitly to int only when needed and eval is for strings, your expression was already in integer terms.
def executeproth():
r = input("Number to test:")
n = int(r) - 1
d = 2
factors = []
while n % 2 == 0:
factors.append(d)
n = n // d
h = len(factors)
#print(n, factors, h)
else:
print"{} = ( 2 ^ {} ) * {} + 1".format(r,h,n)
return factors
executeproth()
First of all, you don't need to explicitly convert a value to an int just to use it in an expression in general. You do need it when processing the input since input() returns a string.
It is more idiomatic to use integer division a // b instead of int(a/b) in python 3.
Finally, eval is for evaluating strings, not expressions. Expressions are always evaluated.
from math import *
def executeproth():
r = input("Number to test:")
n = int(r)-1
d = 2
factors = []
while n % 2 == 0:
factors.append(d)
n = n // d
h = len(factors)
print(n, factors, h)
k = 2**h
# does the same thing but is less efficient
# k = eval("2**h")
return factors
executeproth()
As others have said you don't need eval here. In fact, you should generally avoid using eval since it can be dangerous. And in most situations where you do need to evaluate an expression in string form you can generally get by with the much safer ast.literal_eval. However, at this stage of your learning it's unlikely that you will encounter many situations where you need to work with such advanced features of the language.
Anyway, here are a few more improvements to your code.
You don't need to import the math module since you aren't using any of the functions or constants defined in it. But when you do need to import a module it's best to avoid the from module_name import * form since that pollutes your namespace with all of the names defined in the module.
You don't need to store those 2s in a list - just count them.
It's better to do your input (and input validation) in the outer layers of your program rather than doing it deep in the functions that perform your calculations.
Python provides various augmented assignment operators that you can use when you want to perform a simple operation on a value and store the result back under the original name. Eg count += 1 adds 1 to count, saving the result in count.
Python allows you to return multiple objects as a tuple, so you can return the final value of n and the count of the number of factors of 2 that you've found.
def executeproth(r):
n = r - 1
count = 0
if r != 0:
while n % 2 == 0:
count += 1
n //= 2
return n, count
r = int(input("Number to test: "))
n, count = executeproth(r)
k = 2 ** count
print("{0} = {1} * 2 ** {2} + 1".format(r, n, count))
#v = n*k + 1
#if v != r:
# print("Error!")
The if r != 0: prevents infinite looping if r is zero.
I've also added a (commented-out) test at the end. It's a good idea to do simple tests like that to make sure we're getting what we expect. Writing useful tests is an important part of program development.
Typical output:
Number to test: 0
0 = -1 * 2 ** 0 + 1
Number to test: 29
29 = 7 * 2 ** 2 + 1
Number to test: 57
57 = 7 * 2 ** 3 + 1
def sumdigits(number):
if number==0:
return 0
if number!=0:
return (number%10) + (number//10)
this is the function that I have. However its only give the proper sum of 2 digit numbers. How can i get the sum of any number.
Also would my function count as recursion
def main():
number=int(input("Enter a number :"))
print(sumdigits(number))
main()
No, it is not recursive as you are not calling your function from inside your function.
Try:
def sumdigits(number):
if number == 0:
return 0
else:
return (number%10) + sumdigits(number//10)
Recursion is a way of programming or coding a problem, in which a function calls itself one or more times in its body.
Usually, it is returning the return value of this function call. If a function definition fulfils the condition of recursion, we call this function a recursive function.
A recursive function has to terminate to be used in a program.
Usually, it terminates, if with every recursive call the solution of the problem is downsized and moves towards a base case.
A base case is a case, where the problem can be solved without further recursion. (a recursion can lead to an infinite loop, if the base case is not met in the calls).
For this problem, the "base case" is:
if number == 0:
return 0
A simple recursive function for sum all the digits of a number is:
def sum_digits(number):
""" Return the sum of digits of a number.
number: non-negative integer
"""
# Base Case
if number == 0:
return 0
else:
# Mod (%) by 10 gives you the rightmost digit (227 % 10 == 7),
# while doing integer division by 10 removes the rightmost
# digit (227 // 10 is 22)
return (number % 10) + sumdigits(number // 10)
If we run the code we have:
>>>print sum_digits(57) # (5 + 7) = 12
12
>>>print sum_digits(5728) # (5 + 7 + 2 + 8) = 22
22
For a function to be recursive, it must call itself within itself. Furthermore, since your current one does not do this, it is not recursive.
Here is a simple recursive function that does what you want:
>>> def sumdigits(n):
... return n and n%10 + sumdigits(n//10)
...
>>> sumdigits(457)
16
>>> sumdigits(45)
9
>>> sumdigits(1234)
10
>>>
You don't make a recursive step (calling sumdigits() inside)!
I believe this is what you are looking for:
def sum_digits(n):
if n < 10:
return n
else:
all_but_last, last = n // 10, n % 10
return sum_digits(all_but_last) + last
While recursion is a clever way to go, I'd generally stay away from it for performance and logic reasons (it can get complex pretty quick). I know it's not the answer you are looking for but I'd personally stick to something like this or some kind of loop:
def sumdigits(number):
return sum(map(int, str(number)))
Good luck!
I was working on this recently hope it will help someone in future
def digit(n):
p=0
for i in str(n):
p += int(i)
return p
def superDigit(n):
if n==0:
return 0
return digit(digit(digit(digit(n))))
Here's a solution to summing a series of integer digits that uses ternary operators with recursion and some parameter checking that only happens the first time through the function. Some python coders may consider this less pythonic (using ternary expressions), however, it demonstrates how to use recursion, answering the original question, while introducing ternary operators to combine a few multi-line if/else statements into simple math.
Note that:
int * True = int, whereas int * False = 0
float * True = Float, whereas float * False = 0
"Text" * True = "Text", but "Text" * False = ""; but also
"Text" * 0 = "", whereas "Text" * 3 = "TextTextText"
"Text" * float = Error; whereas "Text" * int = Error
The one-line if/else statement reads as follows:
Expression_if_True if Condition_to_Check else Expression_if_False
def digitSum2(n = 0, first = True):
if first:
first = False
if type(n) != int or n < 0:
return "Only positive integers accepted."
return (n * (n < 10) + (n % 10 + digitSum2(n // 10, first)) * (n >= 10)) if (n > 0) else 0
This is a rather difficult challenge for me as I am new to Python. How would I write a program in python based off this sequence function:
http://oeis.org/A063655
and does the following:
It asks for the value of the sequence and returns the corresponding number. For example, the number corresponding to the 10th value of the sequence is 7. I'd like to be able to do this for values over 300,000,000.
So, the final product would look like this:
Enter a value: 4
[7]
Any ideas where to start? I have a framework to generate sequences where (x) would be to put a mathematical equation or numbers, but I'm not exactly sure how to go from here or how to implement the "Enter a value" portion:
import math
def my_deltas():
while True:
yield (x)
yield (x)
def numbers(start, deltas, max):
i=start
while i<=max:
yield i
i+=next(deltas)
print(','.join(str(i) for i in numbers((x), my_deltas(),(x))))
If you're looking to have your computer keep track of over 300,000,000 elements of a sequence, if each is a 4 byte integer, you'll need at least 300,000,000 * 4bytes, or over 1.1GB of space to store all the values. I assume generating the sequence would also take a really long time, so generating the whole sequence again each time the user wants a value is not quite optimal either. I am a little confused about how you are trying to approach this exactly.
To get a value from the user is simple: you can use val = input("What is your value? ") where val is the variable you store it in.
EDIT:
It seems like a quick and simple approach would be this way, with a reasonable number of steps for each value (unless the value is prime...but lets keep the concept simple for now): You'd need the integer less than or equal to the square root of n (start_int = n ** .5), and from there you test each integer below to see if it divides n, first converting start_int to an integer with start_int = int(start_int) (which gives you the floor of start_int), like so: while (n % start_int) != 0: start_int = start_int - 1, decrement by one, and then set b = start_int. Something similar to find d, but you'll have to figure that part out. Note that % is the modulus operator (if you don't know what that is, you can read up on it, google: 'modulus python'), and ** is exponentiation. You can then return a value with the return statement. Your function would look something like this (lines starting with # are comments and python skips over them):
def find_number(value):
#using value instead of n
start_int = value ** .5
start_int = int(start_int)
while (n % start_int) != 0:
#same thing as start_int = start_int - 1
start_int -= 1
b = start_int
#...more code here
semiperimeter = b + d
return semiperimeter
#Let's use this function now!
#store
my_val = input("Enter a value: ")
my_number = find_number(my_val)
print my_number
There are many introductory guides to Python, and I would suggest you go through one first before tackling implementing a problem like this. If you already know how to program in another language you can just skim a guide to Python's syntax.
Don't forget to choose this answer if it helped!
from math import sqrt, floor
def A063655(n):
for i in range(floor(sqrt(n)), 0, -1):
j = floor(n / i)
if i * j == n:
return i + j
if __name__ == '__main__':
my_value = int(input("Enter a value: "))
my_number = A063655(my_value)
print(my_number)
USAGE
> python3 test.py
Enter a value: 10
7
> python3 test.py
Enter a value: 350000
1185
>