How can I shorten this python code thats using random? [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
How can I shorten this code so it has same functionality?
from random import *
throw1 = randint(1,6)
throw2 = randint(1,6)
throw3 = randint(1,6)
throw4 = randint(1,6)
throw5 = randint(1,6)
throw6 = randint(1,6)
print(throw1, throw2, throw3, throw4, throw5, throw6)
if throw1 == throw2 == throw3 == throw4 == throw5 == throw6:
print(throw1 + throw2 + throw3 + throw4 + throw5 + throw6 + 100)
else:
print(throw1 + throw2 + throw3 + throw4 + throw5 + throw6)

without using any other modules:
>>> import random
# k == number of dice rolls
>>> throws = random.choices(range(1, 7), k=6)
>>> print(*throws)
5 5 6 5 3 6
>>> print(sum(throws) + (100 if all(throws[0] == t for t in throws[1:]) else 0))
30

It looks like list comprehension and itertools.groupby could be useful here.
from random import randint
from itertools import groupby
# generate 6 random integers
throws = [ randint( 1, 6 ) for _ in range( 6 ) ]
# group values in throws
groups = itertools.groupby( throws )
# if all elements are equal, only one element will exist in the groups
score = sum( throws )
if len( groups ) == 1:
print( f'All elements are equal. Score: {score + 100}' )
else:
print( f'Not all elements are equal. Score: {score}' )

Not sure what the goal is, but I would store the throws in a list for a start:
from random import *
throw = [randint(1,6) for _ in range(6)]
print(*throw)
if len(set(throw))==1:
print(sum(throw)+100)
else:
print(sum(throw))

Related

How to change √243 to 9√3 in python? And how to change squared root generally? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I have a math/python question, how to change big number in squared root, to small number (but still keeping the value), for example √243 to 9√3?
And I have another question, how to use it in my code?
Code:
import math
dl=int(input("Podaj długość: "))
c=input("Który bok: przypdl, przypkr, przec: ")
def find(x):
global przypkr
global przec
global przypdl
if c=="przec":
przec=x
przypkr=x/2
przypdl=przypkr*math.sqrt(3)
elif c=="przypkr":
przypkr=x
przypdl=x*math.sqrt(3)
przec=x*2
else:
przypdl=x
przypkr=x/math.sqrt(3)
przec=przypkr*2
print(f'przeciwprostokątna: {przec}, krótsza przyprostokątna: {przypkr}, dłuższa przyprostokątna: {przypdl} √{przypdl*przypdl}')
find(dl)
def obw():
print(f'Obwód równa się: {przec + przypkr + przypdl} lub {przec + przypkr} + √{przypdl*przypdl}')
obw()
Use simplify from SymPy package:
Python env: pip install sympy
Anaconda env: conda install sympy
import sympy as sp
expr = sp.sqrt(243)
print(sp.simplify(expr))
Output:
9*sqrt(3)
The way I thought of this is that we can recursively remove square factors from the root.
e.g.
243
/ \
3^2 27
/ \
3^2 3
The final result on the right (i.e. 3) will be the simplified root, since we've removed all the square factors. The numbers on the left (3 * 3 == 9) will be what we take out the root.
First, we need a way of telling whether a number is square. From another question:
import math
def is_square(i: int) -> bool:
return i == math.isqrt(i) ** 2
Next, we need to be able to determine the factors of a number. I put together something rudementary here, although it can certainly be made more efficient (better examples here):
def factors(i: int) -> list[int]:
factors = []
for number in range(1, i + 1):
if i % number == 0:
factors.append(number)
return factors
Now, we can generate the factors of a number which are square:
>>> [a for a in factors(20) if is_square(a)]
[1, 4]
Putting this all together, we can generate the number outside the square root. Our base case is when the root is already simplified. This means that its only square factor is 1.
Otherwise, we generate what the number outside should be after removing one factor, and we keep repeating this process.
def outside(i: int) -> int:
square_factors = [a for a in factors(i) if is_square(a)]
# Factors are sorted in increasing order.
# Therefore, take any factor that's not 1
factor = square_factors[-1]
if factor == 1:
return 1
# Double slash usage e.g. 7.0 => 7. Could alternatively use int
return int(math.sqrt(factor) * outside(i // factor))
>>> outside(243)
9 # 9 root 3
>>> outside(20)
2 # 2 root 5
Finally, we need to generate the number inside the root. e.g. If its outside number is 3, we divided the original number by 3^2 == 9 to get the simplified root.
def inside(i: int) -> int:
return i // (outside(i) ** 2)
>>> inside(20)
>>> 5 # 2 sqrt 5
>>> inside(243)
>>> 3 # 9 sqrt 3
Putting this all together:
def simplify(i: int) -> tuple[int, int]:
return outside(i), inside(i)
>>> simplify(243)
(9, 3) # 9 sqrt 3
>>> simplify(10)
(1, 10) # 1 sqrt 10
>>> simplify(20)
(2, 5) # 2 sqrt 5
You could find the largest root that is a divisor of your number and present the remainder as the √xxx part:
def root(N):
for r in range(int(N**0.5)+1,1,-1):
if N % (r*r) == 0:
n = N // (r*r)
return str(r) + f"√{n}"*(n>1)
return f"√{N}"
print(root(50)) # 5√2
print(root(81)) # 9
print(root(96)) # 4√6
print(root(97)) # √97
It is usually better to separate computations from formatting using two single purpose functions:
def unroot(N): # find multiplier and remaining root
m,d = 1,2
while d*d<=N:
if N % (d*d): d += 1 + d%2
else: m,N = m*d,N//(d*d)
return m,N
def rootstr(N): # format into a string
m,n = unroot(N)
return str(m)*(m>1)+f"√{n}"*(n>1)
for N in (50,81,96,97):
print(f"√{N} =",rootstr(N))
√50 = 5√2
√81 = 9
√96 = 4√6
√97 = √97

show function approaches certain value [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
the following is my code for to solve this question :
wrote three functions to Show that as n increases (e.g. with a doubling experiment), from n = 2 to n = 1,000, the value of “day_sim(n)” approaches “sqrt(pi * n / 2)”.
"show that is approaching “sqrt(pi * n / 2)” -> but the graph doesn't look like it is approaching to such sqrt value at all...
Please help me with cracking this
import random
from random import randint
import numpy as np
def randomgen(n):
np.random.randint(low = 0, high = n)
return random.randint(0,n-1)
randomgen(100)
def day(n):
result = []
random = randomgen(n)
count =0
while random not in result:
result.append(random)
random = randomgen(n)
count += 1
return count
day(100)
def day(n):
result = []
random = randomgen(n)
count =0
while random not in result:
result.append(random)
random = randomgen(n)
count += 1
return count
def day_sim(n):
n_trails = 10000
for n in range(2,n_trails,50):
sq_rt = math.sqrt(math.pi*n/2)
day_sim = day(n)
print("n =",n,"Absolute difference=",abs(sq_rt - day_sim),"SQ value",sq_rt)
plt.scatter(n,day_sim, color='skyblue')
plt.scatter(n,sq_rt, color='red')
plt.xlim(0,10000)
plt.ylim(0,200)
day_sim(n_trails)
enter image description here
One way to do this would be to plot the variance as you progress:
variance = the (x - y^)**2/n
results = []
for n in range(2000):
y = day_sim(n)
x = (math.pi*n/2)**.5
variance = (x-y)**2/n
results.append((n, variance))
then plot the results and you should see the variance approach zero

creating a set of consecutive non-overlapping bounds from a larger given bounds [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
If a bound is given as (40,260) and it needs to be divided into 4 equal smaller consecutive non-overlapping bounds (i.e.,(40,95),(96,150),(151,205),(206,260))
I tried the following method.
def range_non_overlapping(range_left, range_right, range_per_cut, cut_num)
ranges=[]
for i in range(cut_num):
ranges.append(range_left + i * range_per_cut)
ranges.append(min(range_right, (range_left + (i + 1) * range_per_cut)))
return ranges
But the following code results in overlapping regions on the boundaries [40,95,95,150,150,205,205,260] (pairs from the beginning of the list is a smaller bound). I need to create [40,95,96,150,151,205,206,260]
def chunknize(start, stop, num):
step = (stop - start) / num
return [
(start + i * step + (0 if i == 0 else 1),
start + (i + 1) * step)
for i in range(num)]
print(chunknize(40, 260, 4))
# [(40.0, 95.0), (96.0, 150.0), (151.0, 205.0), (206.0, 260.0)]
If the endpoints are inclusive, then you can't get 4 equal regions, because the size (221) is not a multiple of 4. I would argue that you want (40,94), (95,149), (150,204), (205,260)), which you can do by:
def divide( left, right, cuts ):
delta = (right-left+1) // cuts
out = []
for i in range(cuts):
out.append( left )
left += delta
out.append( left - 1 )
out[-1] = right
return out
print( divide( 40, 260, 4 ) )
Those regions are 55, 55, 55, and 56.

Solve equation in python [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am new to python (24 hours old).
I am trying to create a program in python that can help me solve equations.
For example: To calculate profit, the general, and a very simple equation for a manufacturing unit should be:
Labor-hour-rate*(hours_worked) + No_of_units_produced*raw_material_cost = Total cost.
Now, in this equation there 5 variables. I want to create a program where I input 4 of the 5 variables, the 5th variable should be calculated.
For e.g., If I input
Labour-hour-rate = 20
hours_worked = 2
No_of_units_produced = 10
Total Cost = 80
then, the program should calculate, raw_material_cost = 4
I know one way is to create a separate function for each parameter, but I think there must be a smarter way to do it in Python
Can anyone help me with this?
Thanks
Himanshu
You can solve using namedtuple. And what you want to find set is as None.
import collections
def calculate(args):
if args.total_cost is None:
total_cost = (args.labour_hour_rate * args.hours_worked) + (args.no_of_units_produced * args.raw_material_cost)
print("total_cost =", total_cost)
elif args.hours_worked is None:
hours_worked = (args.total_cost - args.no_of_units_produced * args.raw_material_cost) / args.labour_hour_rate
print("hours_worked =", hours_worked)
elif args.labour_hour_rate is None:
labour_hour_rate = (args.total_cost - args.no_of_units_produced * args.raw_material_cost) / args.hours_worked
print("labour_hour_rate =", labour_hour_rate)
elif args.no_of_units_produced is None:
no_of_units_produced = (args.total_cost - args.labour_hour_rate * args.hours_worked) / args.raw_material_cost
print("no_of_units_produced =", no_of_units_produced)
elif args.raw_material_cost is None:
raw_material_cost = (args.total_cost - args.labour_hour_rate * args.hours_worked) / args.no_of_units_produced
print("raw_material_cost =", raw_material_cost)
Variables = collections.namedtuple("Equation", "labour_hour_rate hours_worked no_of_units_produced total_cost raw_material_cost")
calculate(Variables(20, 2, 10, 80, None))
calculate(Variables(20, 2, 10, None, 4))
calculate(Variables(20, 2, None, 80, 4))
calculate(Variables(20, None, 10, 80, 4))
calculate(Variables(None, 2, 10, 80, 4))
Output:
raw_material_cost = 4.0
total_cost = 80
no_of_units_produced = 10.0
hours_worked = 2.0
labour_hour_rate = 20.0

Python vampire number [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
First time posting in this community. I recently started to learn Python (2 weeks) and as a way to practice a classmate gave me a task: "Write a program that checks if an integer is a vampire number.
For an integer to be a vampire number(v) it needs to meet these 4 criteria:
1)Has a pair number of digits. Lets call the number of digits:n
2)You can obtain v by multiplying two integers,x and y, each with n/2 digits. x and y are the fangs.
3)Both fangs cannot end simultaneously in 0.
4)v can be made with all digits from x and y, in any order and only using each digit once.
Example:
21*60=1260 <--Vampire number
210*600=126000 <--Not a vampire number
The first vampire numbers are the following: 1260, 1395, 1435, 1530, 1827, 2187, 6880, 102510, 104260, 105210, 105264, 105750, 108135, 110758, 115672, 116725, 117067, 118440, 120600, 123354, 124483, 125248, 125433, 125460, 125500, 126027, 126846, 129640, ...
So far I've made a program that can achieve the first 3 criteria(I think). I'm looking for help on the last one.
This is what I've got: (Sorry for some stuff in Spanish)
v=int(input("Enter number to test for vampire:"))
#Test for pair number of digits
def nd(a):
nd = 0
while a != 0:
d = a % 10
if d != 0:
nd += 1
a = a // 10
return nd
def DigitosPar(a):
if nd(a)%2==0:
return 1
else:
return 0
#Last digit is 0
def UltimoDigCero(b):
ud = 0
ud = b % 10
if ud==0:
return 1
else:
return 0
if DigitosPar(v)==1:
x=[]
for i in range(int(10**(nd(v)/2-1)),int(10**(int(nd(v))/2))):
x.append(i)
y=x
z=0
posiblex=0
posibley=0
for ia in range(0,len(y)):
for ib in range(0,len(x)):
z=y[ia]*x[ib]
if z==v and not((UltimoDigCero(x[ib])==1 and UltimoDigCero(y[ia])==1)):
posiblex=x[ib]
posibley=y[ia]
print(v,"has as fangs",posiblex,posibley)
if posiblex==0:
print(v, "not a vampire")
else:
print(v, "not a vampire")
Here is fast method to get solutions for numbers that are 6 digits or longer:
import itertools as it
def get_fangs(num_str):
num_iter = it.permutations(num_str, len(num_str))
for num_list in num_iter:
v = ''.join(num_list)
x, y = v[:int(len(v)/2)], v[int(len(v)/2):]
if x[-1] == '0' and y[-1] == '0':
continue
if int(x) * int(y) == int(num_str):
return x,y
return False
def is_vampire(m_int):
n_str = str(m_int)
if len(n_str) % 2 == 1:
return False
fangs = get_fangs(n_str)
if not fangs:
return False
return True
for test_num in range(150000):
if is_vampire(test_num):
print ("{}".format(test_num), end = ", ")
And here is the output when I run this (in IDLE):
>>>
================== RESTART: C:\Users\Joe\Desktop\vampire.py
1260, 1395, 1435, 1530, 1827, 2187, 6880, 102510, 104260, 105210, 105264,
105750, 108135, 110758, 115672, 116725, 117067, 118440, 120600, 123354,
124483, 125248, 125433, 125460, 125500, 126027, 126846, 129640, 129775,
131242, 132430, 133245, 134725, 135828, 135837, 136525, 136948, 139500,
140350, 143500, 145314, 146137, 146952,
==================
>>>
1260 is a vampire number because the divisors can be concatenated into a permutation of 1260. You can do it this way
v=int(input("Enter number to test for vampire:"))
from collections import Counter
def is_anagram(a, b):
if len(a) != len(b):
return False
return Counter(a) == Counter(b)
import math
for x in range(0,int(math.pow(10, len(str(v))/2))):
for y in range(0,int(math.pow(10, len(str(v))/2))):
if (x*y == v):
#print('Fangs: %d %d' % (x, y))
if (is_anagram(str(str(x)+''+str(y)), str(v)) ):
print('Vampire')
To list the first nvampire numbers, you can use the above code as a function and incrementally test the integers.

Categories