Python - User Input For Arithmetic Progression [duplicate] - python

This question already has answers here:
accepting multiple user inputs separated by a space in python and append them to a list
(4 answers)
Closed 7 years ago.
I am trying to create a function that calculates the sum of an artithmetic sequence. I know how to set up the mathematical calculations but I don't know how to take input from the user to actually perform them.
How can I take user input (like below) such that the three ints on each line are read as A, B, N, with A being the first value
of the sequence, B being the step size and N the number of steps.
8 1 60
19 16 69
17 4 48
What should come next?
def arithmetic_progression():
a = raw_input('enter the numbers: ')

with raw_input you generally get a string
>> a = raw_input('enter the numbers')
you enter the numbers 8 1 60, so a will be a string '8 1 60'. Then you can split the string into the 3 substrings
>> b = a.split()
This will return you a list ['8', '1', '60']. Out of this you can get your numbers
>> A = int(b[0])
>> B = int(b[1])
>> N = int(b[2])
To read multiple lines you could add a function similar to this
def readlines():
out = raw_input('enter the numbers\n')
a = 'dummy'
while(len(a)>0):
a = raw_input()
out += '\n' + a
return out
This function would read any input and write it to the out string until you have one empty line. To get the numbers out of the string just do again the same as for a single line.

Sum to n terms of AP is: Sn = (n/2) [ 2a + (n-1)d ]
def arithmetic_progression():
inp = raw_input('enter the numbers: ').split(' ')
if not len(inp) == 3: # in case of invalid input
return arithmetic_progression() # prompt user to enter numbers again
a = float(inp[0])
d = float(inp[1])
n = float(inp[2])
s = ( (2 * a) + ((n - 1) * d) ) * (n / 2)
print('Sum to n terms of given AP is: ' + str(s))
arithmetic_progression()

Related

sum of every other digit and doubling the rest

I'm working on a card number check code, for now I created a function that asks for the card number and checks if it is 8 digits or not (it has to be 8) and then calls another function that will do the math and check if the card is valid. For this function:
Starting from the rightmost digit, form the sum of every other digit. For example, if the card number is 1234 5678, then you form the sum 8 + 6 + 4 + 2 = 20
Double each of the digits that were not included in the preview step and then add all digits of the resulting numbers. For example, the digits that were not included are 7 5 3 1, we double the, 14 10 6 2, and then we sum each digit, 1 + 4 + 1 + 0 + 6 + 2 = 14
Add the sums of the two steps, 20 + 14 = 34, if the last digit is 0 then the card is valid, otherwise it is not valid (which is our case)
My problem is that I don't know how to iterate and get the sum of every other digit or double the other number which were not included in step 2. My thought was to use a while loop but then what?
EDIT: since some answers used lists... we didn't study lists yet, so I should not use it, we are only allowed to use sample stuff, loops, functions, etc.. even sum(map()) we didn't study
That is my code for now (its not much but just thought put it anyway)
def getCard():
CardInput = int(input("Enter your 8 digit credit card number: "))
if len(CardInput) == 8:
CardCheck(CardInput)
else:
print("Invalid Input: Should be exactly 8 digits!")
getCard()
def CardCheck(CardNumber):
Position = 0
Sum = 0
DoubleSum = 0
FinalSum = 0
while CardNumber >= 0:
Position += 1
So, the ugly way of doing is, you can write a for loop and use indexing for access specific elements
for i in range(len(CardInput)):
# it will iterate from 0 to 7
print(CardInput[i]) # here you get ith element
if i % 2 == 1:
print("I am other!") # you can sum your things here into another variable
Or with while:
while position < len(CardInput):
print(CardInput[position])
position += 1
It assumes CardInput is str, so I recommend to not convert it earlier.
However pythonic way would be
sum(map(int, CardInput[1::2])))
CardInput[1::2] returns list of every second element starting from second (0 is first).
map converts every element to in.
sum sums elements.
prompt = "Enter the eight-digit number: "
while True:
number = input(prompt)
if len(number) == 8 and number.isdigit():
break
prompt = "Oops, try again: "
first_digits = number[1::2] # If the user entered '12345678', this will be the substring '2468'
first_sum = sum(map(int, first_digits)) # Take each digit (character), map it to a single-digit integer, and take the sum of all single-digit integers
second_digits = number[0::2] # If the user entered '12345678', this will be the substring '1357'
doubled_ints = [int(char) * 2 for char in second_digits] # Take each digit (character), turn it into an integer, double it, and put it in a list.
second_sum = sum(map(int, "".join(map(str, doubled_ints)))) # Merge all integers in 'doubled_ints' into a single string, take each character, map it to a single digit integer, and take the sum of all integers.
total_sum = first_sum + second_sum
total_sum_last_digit = str(total_sum)[-1]
is_valid_card = (total_sum_last_digit == '0')
if is_valid_card:
print("Your card is valid (total sum: {})".format(total_sum))
else:
print("Your card is NOT valid (total sum: {})".format(total_sum))
def getCard():
CardInput = input("Enter your 8 digit credit card number: ")
if len(CardInput) == 8:
CardCheck(CardInput)
else:
print("Invalid Input: Should be exactly 8 digits!")
getCard()
def CardCheck(CardNumber):
list_CardNumber = [x for x in "25424334"]
Sum = sum(int(x) for x in list_CardNumber[1:8:-2])
DoubleSum = 2*sum(int(x) for x in list_CardNumber[0:8:-2])
FinalSum = Sum + DoubleSum
if str(FinalSum)[-1] == "0":
print("Valid Input")
else:
print("Invalid Input")
To get you started, you should check out enumerate(), it'll simplify things if you're just going to use loops by giving you easy access to both the index and value every loop.
step1 = 0
for i, x in enumerate(number):
if i % 2:
print('index: '+ str(i), 'value: '+ x)
step1 += int(x)
print('step 1: ', step1)
Output:
index: 1 value: 2
index: 3 value: 4
index: 5 value: 6
index: 7 value: 8
step 1: 20
You can use:
# lets say
CardNumber = '12345678'
# as mentioned by kosciej16
# get every other digit starting from the second one
# convert them to integers and sum
part1 = sum(map(int, CardNumber[1::2]))
# get every other digit starting from the first one
# convert them to integers and double them
# join all the digits into a string then sum all the digits
part2 = sum(map(int,''.join(list(map(lambda x: str(int(x)*2), CardNumber[0::2])))))
result = part1 + part2
print(result)
Output:
34
Edit:
Only with loops you can use:
# lets say
CardNumber = '12345678'
total_sum = 0
for idx, digit in enumerate(CardNumber):
if idx % 2 == 1:
total_sum += int(digit)
else:
number = str(int(digit)*2)
for d in number:
total_sum += int(d)
print(total_sum)
output:
34
Since you need to iterate over the digits, it's actually easier IMO if you leave it as a string, rather than converting the input to an int; that way you can just iterate over the digits and convert them to int individuall to do math on them.
Given an 8-digit long string card, it might look like this, broken into steps:
even_sum = sum(int(n) for n in card[1::2])
double_odds = (2 * int(n) for n in card[0::2])
double_odd_sum = sum(int(c) for do in double_odds for c in str(do))
All together with some logic to loop while the input is invalid:
def get_card() -> str:
"""Returns a valid card number, or raises ValueError."""
card = input("Enter your 8 digit credit card number: ")
if len(card) != 8 or not card.isdecimal():
raise ValueError("Invalid input: Should be exactly 8 digits!")
card_check(card)
return card
def card_check(card: str) -> None:
"""Raises ValueError if card checksum fails, otherwise returns None."""
even_sum = sum(int(n) for n in card[1::2])
double_odds = (2 * int(n) for n in card[::2])
double_odd_sum = sum(int(c) for do in double_odds for c in str(do))
if (even_sum + double_odd_sum) % 10:
raise ValueError("Card checksum failed!")
while True:
try:
print(f"{get_card()} is a valid card number!")
except ValueError as e:
print(e)

Formatting unknown output in a table in Python

Help! I'm a Python beginner given the assignment of displaying the Collatz Sequence from a user-inputted integer, and displaying the contents in columns and rows. As you may know, the results could be 10 numbers, 30, or 100. I'm supposed to use '\t'. I've tried many variations, but at best, only get a single column. e.g.
def sequence(number):
if number % 2 == 0:
return number // 2
else:
result = number * 3 + 1
return result
n = int(input('Enter any positive integer to see Collatz Sequence:\n'))
while sequence != 1:
n = sequence(int(n))
print('%s\t' % n)
if n == 1:
print('\nThank you! The number 1 is the end of the Collatz Sequence')
break
Which yields a single vertical column, rather than the results being displayed horizontally. Ideally, I'd like to display 10 results left to right, and then go to another line. Thanks for any ideas!
Something like this maybe:
def get_collatz(n):
return [n // 2, n * 3 + 1][n % 2]
while True:
user_input = input("Enter a positive integer: ")
try:
n = int(user_input)
assert n > 1
except (ValueError, AssertionError):
continue
else:
break
sequence = [n]
while True:
last_item = sequence[-1]
if last_item == 1:
break
sequence.append(get_collatz(last_item))
print(*sequence, sep="\t")
Output:
Enter a positive integer: 12
12 6 3 10 5 16 8 4 2 1
>>>
EDIT Trying to keep it similar to your code:
I would change your sequence function to something like this:
def get_collatz(n):
if n % 2 == 0:
return n // 2
return n * 3 + 1
I called it get_collatz because I think that is more descriptive than sequence, it's still not a great name though - if you wanted to be super explicit maybe get_collatz_at_n or something.
Notice, I took the else branch out entirely, since it's not required. If n % 2 == 0, then we return from the function, so either you return in the body of the if or you return one line below - no else necessary.
For the rest, maybe:
last_number = int(input("Enter a positive integer: "))
while last_number != 1:
print(last_number, end="\t")
last_number = get_collatz(last_number)
In Python, print has an optional keyword parameter named end, which by default is \n. It signifies which character should be printed at the very end of a print-statement. By simply changing it to \t, you can print all elements of the sequence on one line, separated by tabs (since each number in the sequence invokes a separate print-statement).
With this approach, however, you'll have to make sure to print the trailing 1 after the while loop has ended, since the loop will terminate as soon as last_number becomes 1, which means the loop won't have a chance to print it.
Another way of printing the sequence (with separating tabs), would be to store the sequence in a list, and then use str.join to create a string out of the list, where each element is separated by some string or character. Of course this requires that all elements in the list are strings to begin with - in this case I'm using map to convert the integers to strings:
result = "\t".join(map(str, [12, 6, 3, 10, 5, 16, 8, 4, 2, 1]))
print(result)
Output:
12 6 3 10 5 16 8 4 2 1
>>>

need help in understanding a code

Can anyone explain this code a little. I can't understand what n does here? We already have taken N = int(input()) as input then why n=len(bin(N))-2? I couldn't figure it out.
N = int(input())
n = len(bin(N))-2
for i in range(1,N+1):
print(str(i).rjust(n) + " " + format(i,'o').rjust(n) + " " + format(i,'X').rjust(n) + " " + format(i,'b').rjust(n))
n counts the number of bits in the number N. bin() produces the binary representation (zeros and ones), as as string with the 0b prefix:
>>> bin(42)
'0b101010'
so len(bin(n)) takes the length of that output string, minus 2 to account for the prefix.
See the bin() documentation:
Convert an integer number to a binary string prefixed with “0b”.
The length is used to set the width of the columns (via str.rjust(), which adds spaces to the front of a string to create an output n characters wide). Knowing how many characters the widest binary representation needs is helpful here.
However, the same information can be gotten directly from the number, with the int.bitlength() method:
>>> N = 42
>>> N.bit_length()
6
>>> len(bin(N)) - 2
6
The other columns are also oversized for the numbers. You could instead calculate max widths for each column, and use str.format() or an f-string to do the formatting:
from math import log10
N = int(input())
decwidth = int(log10(N) + 1)
binwidth = N.bit_length()
hexwidth = (binwidth - 1) // 4 + 1
octwidth = (binwidth - 1) // 3 + 1
for i in range(1, N + 1):
print(f'{i:>{decwidth}d} {i:>{octwidth}o} {i:>{hexwidth}X} {i:>{binwidth}b}')

I have an int 123. How to produce a string "100+20+3" using python?

I have a int 123. I need to convert it to a string "100 + 20 + 3"
How can I achieve it using Python?
I am trying to divide the number first (with 100) and then multiple the quotient again with 100. This seems to be pretty inefficient. Is there another way which I can use?
a = 123
quot = 123//100
a1 = quot*100
I am repeating the above process for all the digits.
Another option would be to do it by the index of the digit:
def int_str(i):
digits = len(str(i))
result = []
for digit in range(digits):
result.append(str(i)[digit] + '0' * (digits - digit - 1))
print ' + '.join(result)
which gives:
>>> int_str(123)
100 + 20 + 3
This works by taking each digit and adding a number of zeroes equal to how many digits are after the current digit. (at index 0, and a length of 3, you have 3 - 0 - 1 remaining digits, so the first digit should have 2 zeroes after it.)
When the loop is done, I have a list ["100", "20", "3"] which I then use join to add the connecting " + "s.
(Ab)using list comprehension:
>>> num = 123
>>> ' + '.join([x + '0' * (len(str(num)) - i - 1) for i, x in enumerate(str(num))])
'100 + 20 + 3'
How it works:
iteration 0
Digit at index 0: '1'
+ ('0' * (num_digits - 1 - iter_count) = 2) = '100'
iteration 1
Digit at index 1: '2'
+ ('0' * 1) = '20'
iteration 2
Digit at index 2: '3'
+
('0' * 0) = '3'
Once you've created all the "numbers" and put them in the list, call join and combine them with the string predicate +.
Another way of achieving what you intended to do:
def pretty_print(a):
aa = str(a)
base = len(aa) - 1
for v in aa:
yield v + '0' * base
base -= 1
>>> ' + '.join(pretty_print(123))
'100 + 20 + 3'
Here's my approach:
numInput= 123
strNums= str(numInput)
numberList= []
for i in range(0,len(strNums)):
digit= (10**i)*int(strNums[-(i+1)])
numberList.append(str(digit))
final= "+".join(numberList)
print(final)
It's the mathematical approach for what you want.
In number system every digit can be denoted as the 10 to the power of the actual place plus number(counting from zero from right to left)
So we took a number and converted into a string. Then in a loop we decided the range of the iteration which is equal to the length of our number.
range: 0 to length of number
and we give that number of power to the 10, so we would get:
10^0, 10^1, 10^2...
Now we need this value to multiply with the digits right to left. So we used negative index. Then we appended the string value of the digit to an empty list because we need the result in a form as you said.
Hope it will be helpful to you.

Using raw_input with functions in Python

I want to execute a function certain number of times as specified by the user, for user-specified values. I have written the following code
queries = int(raw_input("The number of queries to run: "))
for i in range(0, queries):
a, b = raw_input().split(" ")
def count_substring(str):
length = len(str) + 1
found = []
for i in xrange(0, length):
for j in xrange(i+1, length):
if str[i] == a and str[j-1] == b:
found.append(str[i:j])
print len(found)
string = 'aacbb'
print count_substring(string)
The function gives the number of sub-strings that start and end with user specified characters.
For ex:
In the string "aacbb" the number of sub strings starting with a and ending with c are 2.
Queries indicates the number of inputs, ex for queries = 2 , there will be two inputs of the sub strings, i.e a & c or a & b
I want this code to return 2 values as answers, but it returns only 1.

Categories

Resources