I have the following code for example:
n = ['321','243','780']
b = ['12','56','90']
a = ['178', '765', '111']
E = input('Enter Word...')
qw = 1
Code = ('')
E_ready = [E[no:no+qw] for no in range(0, len(E), qw)]
for code in E_Ready:
letter = random.choice(code)
Code += letter
If you enter the word 'nba' then it will output as 'nba', I want it to output with random elements from each letter's respective list so for example '32112178'
As Willem van Onsem correctly mentioned in the comments:
"...that is really bad design, call-by-name is rather unsafe. You better use a dictionary."
So, try this:
n = {'option1':'321','option2':'243','option3':'780'}
letter = random.choice(list(n.values()))
Or, shorter, as Chris has mentioned:
d = {'n':[321, 243, 780]}
letter = random.choice(d['n'])
Results from print(letter) (on both options):
321
321
780
243
etc..
EDIT:
How to add extra variables:
n = 'n'
d = {n:[321, 243, 780]}
letter = random.choice(d[n])
q = 'q'
d[q] = [600, 234, 180]
new_letter = random.choice(d[q])
Now print(new_letter) gives:
234
180
180
600
etc..
SECOND EDIT (which btw is pure bonus since the question turned into a completely different one then first asked.. therefor, it is left unoptimized. Yet, working nonetheless..):
import random
d = {'n':[321, 243, 780], 'b':['12','56','90'], 'a':['178', '765', '111']}
E = input('Enter Word...')
inputword = list(E)
for key in d.keys():
if key in inputword:
for i in range(len(inputword)):
if inputword[i] == key:
try:
inputword[i] = str(random.choice(d[key]))
except:
pass
result = ''.join(inputword)
print(result)
If input = nba then output = 32190111
If input = nhhsygbbvvra then output = 321hhsyg5690vvr178
Etc..
Okay, you have a few fundamental issues.
When you want to assign one variable to another then you wouldn't put it in quotes.
So it should be:
code = n
But actually I'm wondering why you need the variable code at all.
You could simply do
import random
code = [ '321', '243', '780' ]
letter = random.choice(code)
print letter
I agree with the comment, it is better to use something like:
d = {'n':[mylist]}
letter = random.choice(d['n'])
the problem is that random.choice works on strings too... it simply considers them to be a list of characters. in your case the code variable and n are supposed to be exactly the same but are in fact not. You could also do
n = [list]
code = n ## only makes any sense, if there
## is a procedure assigns it based on some condition
letter = random.choice(code)
Related
I'm trying to find a path in a game, you start out with value = 1 and you're supposed to add/multiply it with the right numbers in order until you get 49. For example, if I follow the path of 1+2*3, it'll be more like (1+2)*3 = 9 instead of 1+2*3 = 7.
I tried some code, like this:
result = 0
while result != 49:
values = ["+2","+3","+5","*2","*3","*5"]
pathway = random.sample(values, 5)
pathway = str(pathway)
pathway = pathway.replace("', '", "")
path = "1"+str(pathway)[2:-2]
result = eval(path)
print(path, "=", result)
I got my result pretty quickly, but when I tried it I realized that this function follows the order of operations (multiplication before addition). Is there an easy way to make it count from left to right without prioritising multiplication?
If what you want is to simply calculate 1+2*3 (or something) without order of operations, try this:
def do_math_left_to_right(expression):
pieces = []
i = 0
for c in expression:
if c in digits:
try:
pieces[i] += c
except IndexError:
pieces.append(c)
elif c in {'+', '-', '*', '/'}:
i += 1
pieces.append(c)
last_piece = pieces.pop(0)
result = 0
for piece in pieces:
result = eval(f'{last_piece}{piece}')
last_piece = str(result)
return result
This is a screenshot of the same function but with debugging messages:
The Problem at hand
Currently, I am working towards making a code generator for reasons unnessesary to the question.
The Codes follow the format of 00|letter|8string mix|letter
Examples of expected end results are such:
00b06c1161bc
00aee797645b
00c435ab439e
00da494a229a
A quick breakdown of the middle 8 section string results in the requirement of a maximum of two alpha-characters and 6 numbers that can be in random order.
While Im having difficulty with this, there becomes the added problem of the limited letters accepted. These are the letters, a,b,c,d,e, and f
I've made a list (acceptedChars=["a","b","c","d","e","f"]) for the generator to pull from, however how to allow it to use this towards generation following the requirements I am unsure of how to pull off.
Any info on this would be wonderful, if you have any questions, comment and I will be sure to respond to it.
Here'a full implementation of the code using random function.
This code will generate you 100 random 12 char codes.
The below code also addresses the requirement of a maximum of two alpha-characters and 6 numbers that can be in random order
import random
acceptedChars = list('abcdef')
acceptedDigit = list('0123456789')
for i in range(100):
secretCode = '00' + random.choice(acceptedChars)
charCount = digitCount = 0
pos1 = random.randint(1,8)
pos2 = pos1
while pos2 == pos1: pos2 = random.randint(1,8)
for i in range(1,9):
if i in (pos1,pos2):
secretCode += random.choice(acceptedChars)
else:
secretCode += random.choice(acceptedDigit)
secretCode += random.choice(acceptedChars)
print (secretCode)
Sample output of the random codes (generated 10):
00e89642be3c
00ba75d2130e
00b56c9b906b
00da9294e87c
00b3664ce97f
00c4b6681a3e
00e6699f75cf
00d369d07a0a
00ce653a228f
00d5665f95bd
I think random.choice is what you want:
import random
acceptedChars = ["a","b","c","d","e","f"]
x = random.choice(acceptedChars)
y = random.choice(acceptedChars)
Check this whole code for your problem. Maybe you find something useful. I made it in less complexity than O(n2).
It is the program of random string generation for verification.
This code also fulfills the maximum 2 alpha requirements.
import random
def code():
acceptedChars=["a","b","c","d","e","f"]
first = "00"
second = random.choice(acceptedChars)
third = ""
fourth = random.choice(acceptedChars)
# for third part
slot = random.randint(0,2)
if (slot == 2):
number = str(random.randint(100000,1000000))
alpha1 = random.choice(acceptedChars)
alpha2 = random.choice(acceptedChars)
part1 = random.randint(0,6)
part2 = random.randint(part1,6)
third = number[:part1] + alpha1 + number[part1:part2] + alpha2 + number[part2:]
elif (slot == 1):
number = str(random.randint(1000000,10000000))
alpha = random.choice(acceptedChars)
slot = random.randint(0,8)
third = number[:slot] + alpha + number[slot:]
else:
third = str(random.randint(10000000,100000000))
return first + second + third + fourth
print(code())
Hope it helps.
Output looks like:
00d65262056f
00a317c8015e
00a334564ecf
00e14a657d9c
import string
import random
allowed_chars = string.ascii_letters[:6]
expression = ''.join(random.choices(allowed_chars + string.digits, k=8))
print(f"The generator is 00{str(expression)}")
I'm trying to make a program that lists all the 64 codons/triplet base sequences of DNA...
In more mathematical terms, there are 4 letters: A, T, G and C.
I want to list all possible outcomes where there are three letters of each and a letter can be used multiple times but I have no idea how!
I know there are 64 possibilities and I wrote them all down on paper but I want to write a program that generates all of them for me instead of me typing up all 64!
Currently, I am at this point but I have most surely overcomplicated it and I am stuck:
list = ['A','T','G','C']
list2 = []
y = 0
x = 1
z = 2
skip = False
back = False
for i in range(4):
print(list[y],list[y],list[y])
if i == 0:
skip = True
else:
y=y+1
for i in range(16):
print(list[y],list[y],list[x])
print(list[y],list[x], list[x])
print(list[y],list[x], list[y])
print(list[y],list[x], list[z])
if i == 0:
skip = True
elif z == 3:
back = True
x = x+1
elif back == True:
z = z-1
x = x-1
else:
x = x+1
z = z+1
Any help would be much appreciated!!!!
You should really be using itertools.product for this.
from itertools import product
l = ['A','T','G','C']
combos = list(product(l,repeat=3 ))
# all 64 combinations
Since this produces an iterator, you don't need to wrap it in list() if you're just going to loop over it. (Also, don't name your list list — it clobbers the build-in).
If you want a list of strings you can join() them as John Coleman shows in a comment under your question.
list_of_strings = ["".join(c) for c in product(l,repeat=3) ]
Look for for pemuations with repetitions there tons of code available for Python .
I would just use library , if you want to see how they implemented it look inside the library . These guys usually do it very efficiency
import itertools
x = [1, 2, 3, 4, 5, 6]
[p for p in itertools.product(x, repeat=2)]
This is supposed to become a random name generator in the end, all the random part is working. Only problem is that it is REALLY random, getting weird stuff like aaaaaaaa etc.
So I'm trying to add a rule to not allow 2 vowels after each other (same goes with consonants).
So yeah, guys please help me out here. I've been looking throu' this code for 2 hours now and I cant find the problem.
Just pasting my entire code here.
import random
import string
import numpy as np
from sys import argv
import csv
# abcdefghijklmnopqrstuvwxyz
# Example output: floke fl0ke flok3 fl0k3
#
class facts:
kons = list('bcdfghjklmnpqrstvwxz') #20
voks = list('aeiouy') #6
abc = list('abcdefghijklmnopqrstuvwxyz')
def r_trfa(): #True Or False (1/0)
x = random.randrange(0, 2)
return x;
def r_kons(): #Konsonant
y = random.randrange(0, 20)
x = facts.kons[y]
return x;
def r_vok(): #Vokal
y = random.randrange(0, 6)
x = facts.voks[y]
return x;
def r_len(): #Langd
x = random.randrange(4, 8)
return x;
def r_type():
x = random.randrange(1, 4)
return x;
def r_structure(length): #Skapar strukturen
y = r_type()
if y == 0:
no1 = 1
else:
no1 = 2
i = 0
x = [no1]
y = r_type()
if not no1 == y:
x.append(y)
while i < length:
y = r_type()
if not x[i] == y:
x.append(y)
i = i + 1
x2 = list(x)
return x2;
def name(): #Final product
struct = r_structure(r_len())
name = struct
You've got several bugs. For example, you're checking the value y against 0 even though it is always in the range 1-4, probably unintended behavior. Furthermore, you never actually call a function that gets you a character, and you never create a string. Thus it's not clear what you're trying to do.
Here's how I'd rewrite things based on my guess of what you want to do.
import random, itertools
voks = frozenset('aeiouy')
abc = 'abcdefghijklmnopqrstuvwxyz'
def r_gen():
last=None #both classes ok
while 1:
new = random.choice(abc)
if (new in voks) != last:
yield new
last = (new in voks)
def name(): #Final product
length = random.randrange(4, 8)
return ''.join(itertools.islice(r_gen(), length))
The problem you're having is that your loop increments i always, but only adds an additional value to your x list if the random value doesn't match x[i]. This means that if you get several matches in a row, i may become larger than the largest index into x and so you'll get an IndexError exception.
I'm not entirely sure I understand what you're trying to do, but I think this will do something similar to your current r_structure function:
def r_structure(length):
"""Returns a list of random "types", avoiding any immediate repeats"""
x = [r_type()]
while len(x) < length:
y = r_type()
if y != x[-1]: # check against the last item in the list
x.append(y)
return x
If your goal is simply to randomly generate a sequence of alternating vowels and consonants, there's an easier way than what you seem to be doing. First off, you can use random.choice to pick your characters. Further, rather than picking many letters and rejecting ones that are of the wrong type, you can simply pick from one string, then pick from the other, for as long as you need:
import random
def alternating_characters(length):
characters = ["aeiouy", "bcdfghjklmnpqrstvwxz"]
char_type = random.randrange(2) # pick a random letter type to start with
results = []
while len(char_list) < length:
results.append(random.choice(characters[char_type])) # pick random char
char_type = 1-char_type # pick from the other list next time
return "".join(char_list)
Well it's unclear what you want to do.. As the conditions on vowels and consonants is the same, so why do you need to differentiate between them?
So all you need to do is take a random letter and check that it doesn't match with the last letter.
Here's some code:
import random
abc = 'abcdefghijklmnopqrstuvwxyz'
def gen_word(length):
last = ''
while length > 0:
l = random.choice(abc)
if l != last:
length -= 1
yield l
if __name__ == '__main__':
word = ''.join(gen_word(10))
print word
I'm working on problem 22 of Project Euler:
Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.
For example, when the list is sorted into alphabetical order, COLIN,
which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the
list. So, COLIN would obtain a score of 938 × 53 = 49714.
What is the total of all the name scores in the file?
http://projecteuler.net/problem=22
When I compile my code below, I get the answer 871196077. The correct answer should be 871198282.
import time
def euler_22():
## Creates a sorted list of the names in Py_Euler_22.txt
names = open('Py_Euler_22.txt', 'r')
names = names.read()
names = names.split('","')
names[0] = names[0][1:]
names[-1] = names[-1][:-2]
names = sorted(names)
## Creates a dictionary: letter -> value
value_letters = {}
start = ord("A")
for i in range(0, 26):
value_letters[chr(start+i)] = i+1
result = 0
for i in range(1, len(names)+1):
name = names[i-1]
sum_letters = 0
for letter in name:
sum_letters += value_letters[letter]*i
# = value of the letter multiplied with the name position
result += sum_letters
return result
tstart = time.time()
print euler_22()
print "Run time: " + str(time.time() - tstart)
I tried to find a program with a similar solution, but I only know Python, that limits the options.
I ran the program with simpler text-files, I created, where I can get the answer without a program and all of them worked. I googled the answer to the problem, but that didn't help either, since I cant find the missing points.
I'm a beginner, so I would really appreciate any tips regarding the program and Python, not only those, that will help me to solve the problem correctly.
Thanks a lot!
You have accidentally mangled one name.
Here qnames is the sorted list of names your code produces, and sorted_names is mine:
>>> for a,b in zip(qnames, sorted_names):
... if a != b:
... print a, b
...
ALONS ALONSO
For fun: a one-liner - nested list comprehensions, avast ye!
print sum ( [ (pos+1) * nv for pos, nv in enumerate([ sum ( [ ord(char) - 64 for char in name ] ) for name in sorted([name.strip('"') for name in open('names.txt','r').readline().split(",")]) ]) ] )
Or more readably:
print sum (
[(pos+1) * nv for pos, nv in
enumerate([ sum ([ ord(char) - 64 for char in name ] ) for name in
sorted([name.strip('"') for name in
open('names.txt','r').readline().split(",")]) ]) ] )
The black magic is that ASCII A is integer 65, ASCII B is integer 66, and so on - so ord(char) - 64 gets you the "letter value" of char.
Edit 2:
The full, human-readable, solution that I crammed into one line for your amusement.
with open('names.txt','r') as f:
data = f.readline();
names = [name.strip('"') for name in data.split(",")]
sorted_names = sorted(names)
name_values = [ sum ( [ ord(char) - 64 for char in name ] ) for name in sorted_names ]
name_position_values = [ (pos+1) * nv for pos, nv in enumerate(name_values) ]
total_sum = sum(name_position_values)
# debug output
from pprint import pprint
#position, word value, position * word value, word
pprint(zip(xrange(1,len(names)+1),name_values,name_position_values,sorted_names))
Note the heavy use of list comprehensions [x for x in list_of_xes] instead of loops, and the sum() function instead of for x in xes: sum += x.
There are some other tricks in here, but the take-home lesson is that list comprehensions and functions that process lists can make your code much simpler and easier to read.
Edit 3:
The pprint.pprint() function is a "pretty print()". It's great for debugging.
Edit 4:
Code golf version (142 chars):
print sum([(p+1)*v for p,v in enumerate([sum(map(ord,n))-64*len(n) for n in sorted([n[1:-1] for n in open('names.txt').read().split(",")])])])
I just cross-checked your code, and it looks like you're inadvertently chopping off the last character of the last word. To strip off the quotes from the last word, use:
names[-1] = names[-1][:-1]
Rather than trying to strip all the quotes from the names at once when you're converting the file contents to a list, strip them when you're processing the list.
# Project Euler Problem 22
# Name Scores
def score(name):
total = 0
for char in name:
total += (ord(char) - 64) # scale so A = 1, B = 2...
return total
def main():
# Open the names file for reading
infile = open('names.txt', 'r')
# Read the entire contents of the file
file_contents = infile.read()
# Close the file
infile.close()
# Convert file contents to a list of quoted names and sort them
list_of_names = file_contents.split(',')
list_of_names.sort()
position = 1
total = 0
for name in list_of_names:
name = name.strip('"') # strip the quotes from names individually
total += score(name) * position
position += 1
print(total)
if __name__ == "__main__":
main()