Set N item from a List as a Variable - python

I'm new to Python and writing a small script to set an RGB color where two of the RGB colors are randint(0,255) and the third (selected randomly) is 0.
To acomplish this, I have this:
import time
from random import *
from neopixel import *
print ('Press Ctrl-C to quit.')
while True:
colorList = [0, randint(0,255), randint(0,255)]
shuffle(colorList)
rColor = ???
gColor = ???
bColor = ???
time.sleep(1)
I 'm having a lot of luck finding the answer but if I wanted to extract the first item from the list and set it to rColor, the second for gColor and etc, what Python function could I use to do that?
Edit: My end goal format would be an output that was simply "0, 150, 150". The NeoPixel library I am working with is picky so that is the literal format I am aiming for.

To set the color values to three variables. Use
r, g, b = colorList
or
r = colorList[0]
g = colorList[1]
b = colorList[2]
If the meaning of 'output' is print the result to console. Then use
print(*colorList, sep=', ')
If you need a string '0, 150, 150'
result = ', '.join(map(str, colorList))
or
result = ', '.join([str(x) for x in colorList])

This seems to do the trick.
from time import sleep
from random import randint, shuffle
while True:
color_list = [0, randint(0,255), randint(0,255)]
shuffle(color_list)
r_color, g_color, b_color = color_list
# sets colors to a string like "12, 10, 0"
colors = ', '.join(str(color) for color in color_list)
# print (colors)
sleep(1)
EDIT: added lines to include your edit

Related

Python: Pseudo-random color from a string

I am doing some data visualization with Python in Blender and I need to assign colors to the data being represented. There is too much data to spend time hand-picking colors for each, so I want to generate the colors pseudo-randomly - I would like a given string to always result in the same color. That way, if it appears more than once, it will be clear that it is the same item.
For example, given a list like ['Moose', 'Frog', 'Your Mother'], let's say Moose would always be maroon.
The colors are specified in RGB, where each channel is a float from 0.0 to 1.0.
Here's what I've tried so far that isn't working:
import random
import hashlib
def norm(x, min, max): # this normalization function has a problem
normalized = ( x - min(x) ) / (max(x) - min(x) )
return normalized
def r(string, val):
h = hash(string)
print(h)
if h < 0:
h = h * -1
rs = random.seed( int(h) + int(val) )
output = norm(rs, 0.0, 1.0)
return output
my_list = ['Moose', 'Frog', 'Your Mother']
item = my_list[0]
color = [ r(item,1), r(item,2), (item,1) ]
print(color)
It results in TypeError: 'float' object is not callable but I don't know why. I'm trying to normalize the way this answer demonstrates.
It might be best to have a list of possible colors, as it allows for control over the palette. Either way, I need a pseudo-random float in the range of 0.0 ~ 0.1.
You can try with this function. It returns a rgb value for the name by using the 3 first letters.
def name_color(name):
color = [(ord(c.lower())-97)*8 for c in name[:3]]
return color
It turns out I didn't need to normalize or do anything fancy. random() returns a range between 0.0 ~ 1.0 as it is. I just needed to take a closer look at how random.seed() is supposed to be used.
Here's my solution:
import random
import hashlib
def r(string, int): # pseudo-randomization function
h = hash( string + str(int) ) # hash string and int together
if h < 0: # ensure positive number
h = h * -1
random.seed(h) # set the seed to use for randomization
output = random.random() # produce random value in range 0.0 ~ 1.0
output = round(output, 6) # round to 6 decimal places (optional)
return output
my_list = ['Toyota', 'Tesla', 'Mercedes-Benz']
item = my_list[0] # choose which list item
color = [ r(item,0), r(item,1), r(item,2) ] # R,G,B values
print(item, color)
Output: Toyota [0.049121, 0.383824, 0.635146]
I may try the list approach later.

Create a race in Python?

I'm very new to python 3. As an assignment, I am supposed to make a race in python basic Syntax and without importing any other additional function, where 3 mice are racing with different odds of winning.
from random import randint
import time
def race():
z = '----{,_,">' # The mouse.
j = ' '
print('\t'*13, '|') # The finish line. Very sophisticated.
while len(z) < 50:
time.sleep(1)
#or k in range(3):
x = randint(1, 6)
j = ' ' * x
z = j + z
print("\r" + str(z), end="") # For clearing printed text. I prefer not to import os.
As you might see, I've managed to make one; Two to go. But I've scratching my head for three hours on how to do it, that is how to make them go simultaneously ... Any help will be appreciated.
As you have seen, unfortunately the "\r" character only erases the current line, but it does not erase the others, making it impossible to create the program with this strategy. The only way to do this is to clear the console using multiple print("\n"). See this example:
from random import randint
import time
def clear():
print("\n"*80)
def race(mice = 2):
mice = ['----{,_,">' for i in range(mice)]
finished = [False,]
while not all(finished):
time.sleep(1)
clear()
print('\t' * 13, '|') # The finish line. Very sophisticated.
for i in range(len(mice)):
x = randint(1, 6)
spaces = ' ' * x
mice[i] = spaces + mice[i]
print(mice[i])
finished = map(lambda mouse: False if len(mouse) < 50 else True, mice)
race(3)
Make a function that takes a string (mouse) as an argument; adds a random number of spaces to it and returns the new string.
Make three mice.
For each mouse call the function and assign the result to that mouse.
repeat until one mouse wins - (string is a certain length).

Python 'for' loop issue, wht are these two variables not adding together properly in my 'for' loop?

I am writing a code snippet for a random algebraic equation generator for a larger project. Up to this point, everything has worked well. The main issue is simple. I combined the contents of a dictionary in sequential order. So for sake of argument, say the dictionary is: exdict = {a:1 , b:2 , c:3 , d:4}, I append those to a list as such: exlist = [a, b, c, d, 1, 2, 3, 4]. The length of my list is 8, which half of that is obviously 4. The algorithm is quite simple, whatever random number is generated between 1-4(or as python knows as 0-3 index), if you add half of the length of the list to that index value, you will have the correct value.
I have done research online and on stackoverflow but cannot find any answer that I can apply to my situation...
Below is the bug check version of my code. It prints out each variable as it happens. The issue I am having is towards the bottom, under the ### ITERATIONS & SETUP comment. The rest of the code is there so it can be ran properly. The primary issue is that a + x should be m, but a + x never equals m, m is always tragically lower.
Bug check code:
from random import randint as ri
from random import shuffle as sh
#def randomassortment():
letterss = ['a','b','x','d','x','f','u','h','i','x','k','l','m','z','y','x']
rndmletters = letterss[ri(1,15)]
global newdict
newdict = {}
numberss = []
for x in range(1,20):
#range defines max number in equation
numberss.append(ri(1,20))
for x in range(1,20):
rndmnumber = numberss[ri(1,18)]
rndmletters = letterss[ri(1,15)]
newdict[rndmletters] = rndmnumber
#x = randomassortment()
#print x[]
z = []
# set variable letter : values in list
for a in newdict.keys():
z.append(a)
for b in newdict.values():
z.append(b)
x = len(z)/2
test = len(z)
print 'x is value %d' % (x)
### ITERATIONS & SETUP
iteration = ri(2,6)
for x in range(1,iteration):
a = ri(1,x)
m = a + x
print 'a is value: %d' % (a)
print 'm is value %d' %(m)
print
variableletter = z[a]
variablevalue = z[m]
# variableletter , variablevalue
edit - My questions is ultimately, why is a + x returning a value that isn't a + x. If you run this code, it will print x , a , and m. m is supposed to be the value of a + x, but for some reason, it isnt?
The reason this isn't working as you expect is that your variable x originally means the length of the list, but it's replaced in your for x in range loop- and then you expect it to be equal to the length of the list. You could just change the line to
for i in range(iteration)
instead.
Also note that you could replace all the code in the for loop with
variableletter, variablevalue = random.choice(newdict.items())
Your problem is scope
which x are you looking for here
x = len(z)/2 # This is the first x
print 'x is value %d' % (x)
### ITERATIONS & SETUP
iteration = ri(2,6)
# x in the for loop is referencing the x in range...
for x in range(1,iteration):
a = ri(1,x)
m = a + x

convert list of arrays in python, to tree in grasshopper

I'm a beginner in Python and have a question about converting data structure, for using it in Grasshopper.
As an output from my python code, I have a grid of cubes (GUID's), layered up in what I call 'generations'. Besides that, it outputs a grid of data, which contains the information about what color each cube should get.
For example: for j=5 in i=3, in generation=5, I have a cube. In the other list, for j=5 in i=3 , in generation=5, I have 'green' as a string. In grasshopper, I want to link this 'green' value to a swatch, and then color the right cube with it.
The problem is that Python outputs a three-dimensional array, while Grasshopper works in trees. So, I have to convert my outputs to a tree structure in which the first level is 'generations', the second level is 'i' and the third is 'j'.
A friend sent me this piece of code, so I guess that is how to begin:
import clr
clr.AddReference("Grasshopper")
from Grasshopper.Kernel.Data import GH_Path
from Grasshopper import DataTree
I hope you guys can help!
Tessa
This is my mainfunction:
def Main():
intLength = input1
intWidth = input2
intGen = input3
arrValues = randomizeArray01(intLength,intWidth)
arrDensity = densityfunction(arrValues)
arrMeshes = render(arrValues,-1)
for k in range(intGen):
arrValues = applyGOL(arrValues,arrDensity)
arrDensity = densityfunction(arrValues)
genC = colorObject(arrValues)
colorList.append(genC)
genR = render(arrValues,k)
renderList.append(genR)
In which this is the renderfunction:
def render(arrValues, z):
rs.EnableRedraw(False)
arrMeshes = []
for i in range(len(arrValues)):
arrRow = []
for j in range(len(arrValues[i])):
box = addMeshBox([(i-0.5),(len(arrValues[i])-j-0.5),z-0.5], [(i+0.5),(len(arrValues[i])-j+0.5),z+0.5])
arrRow.append(box)
arrMeshes.append(arrRow)
rs.EnableRedraw(True)
return arrMeshes
And this is the colorfunction:
def colorObject(arrValues):
arrColor = []
for i in range(len(arrValues)):
rowColor= []
for j in range(len(arrValues[i])):
if arrValues[i][j] == 0:
color = green
rowColor.append(color)
elif arrValues[i][j] ==1:
color = residential
rowColor.append(color)
elif arrValues[i][j] ==100:
color = retail
rowColor.append(color)
elif arrValues[i][j] ==1000:
color = road
rowColor.append(color)
arrColor.append(rowColor)
return arrColor
And in the end, this is what I output to Grasshopper:
a = renderList
b = colorList
In grasshopper, this gives me a list of 'Iron.Python.Runtime.List'.
I don't have a working version of grasshopper to hand, but my code for doing this is:
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
from clr import AddReference as addr
addr("Grasshopper")
from System import Object
from Grasshopper import DataTree
from Grasshopper.Kernel.Data import GH_Path
def raggedListToDataTree(raggedList):
rl = raggedList
result = DataTree[object]()
for i in range(len(rl)):
temp = []
for j in range(len(rl[i])):
temp.append(rl[i][j])
#print i, " - ",temp
path = GH_Path(i)
result.AddRange(temp, path)
return result
There is a gist of this here that also has a function that turns trees into lists.
There's still quite a lot wrong with this, no recursion, no error checking, no branch magic, but it does the job in most cases. I'd love to see it improved!
In your case you can just pipe the output that would otherwise give you a runtime list into the raggedListToDataTree function.

Generating a Random Hex Color in Python

For a Django App, each "member" is assigned a color to help identify them. Their color is stored in the database and then printed/copied into the HTML when it is needed. The only issue is that I am unsure how to generate random Hex colors in python/django. It's easy enough to generate RGB colors, but to store them I would either need to a) make three extra columns in my "Member" model or b) store them all in the same column and use commas to separate them, then, later, parse the colors for the HTML. Neither of these are very appealing, so, again, I'm wondering how to generate random Hex colors in python/django.
import random
r = lambda: random.randint(0,255)
print('#%02X%02X%02X' % (r(),r(),r()))
Here is a simple way:
import random
color = "%06x" % random.randint(0, 0xFFFFFF)
To generate a random 3 char color:
import random
color = "%03x" % random.randint(0, 0xFFF)
%x in C-based languages is a string formatter to format integers as hexadecimal strings while 0x is the prefix to write numbers in base-16.
Colors can be prefixed with "#" if needed (CSS style)
little late to the party,
import random
chars = '0123456789ABCDEF'
['#'+''.join(random.sample(chars,6)) for i in range(N)]
Store it as a HTML color value:
Updated: now accepts both integer (0-255) and float (0.0-1.0) arguments. These will be clamped to their allowed range.
def htmlcolor(r, g, b):
def _chkarg(a):
if isinstance(a, int): # clamp to range 0--255
if a < 0:
a = 0
elif a > 255:
a = 255
elif isinstance(a, float): # clamp to range 0.0--1.0 and convert to integer 0--255
if a < 0.0:
a = 0
elif a > 1.0:
a = 255
else:
a = int(round(a*255))
else:
raise ValueError('Arguments must be integers or floats.')
return a
r = _chkarg(r)
g = _chkarg(g)
b = _chkarg(b)
return '#{:02x}{:02x}{:02x}'.format(r,g,b)
Result:
In [14]: htmlcolor(250,0,0)
Out[14]: '#fa0000'
In [15]: htmlcolor(127,14,54)
Out[15]: '#7f0e36'
In [16]: htmlcolor(0.1, 1.0, 0.9)
Out[16]: '#19ffe5'
This has been done before. Rather than implementing this yourself, possibly introducing errors, you may want to use a ready library, for example Faker. Have a look at the color providers, in particular hex_digit.
In [1]: from faker import Factory
In [2]: fake = Factory.create()
In [3]: fake.hex_color()
Out[3]: u'#3cae6a'
In [4]: fake.hex_color()
Out[4]: u'#5a9e28'
Just store them as an integer with the three channels at different bit offsets (just like they are often stored in memory):
value = (red << 16) + (green << 8) + blue
(If each channel is 0-255). Store that integer in the database and do the reverse operation when you need to get back to the distinct channels.
import random
def hex_code_colors():
a = hex(random.randrange(0,256))
b = hex(random.randrange(0,256))
c = hex(random.randrange(0,256))
a = a[2:]
b = b[2:]
c = c[2:]
if len(a)<2:
a = "0" + a
if len(b)<2:
b = "0" + b
if len(c)<2:
c = "0" + c
z = a + b + c
return "#" + z.upper()
So many ways to do this, so here's a demo using "colorutils".
pip install colorutils
It is possible to generate random values in (RGB, HEX, WEB, YIQ, HSV).
# docs and downloads at
# https://pypi.python.org/pypi/colorutils/
from colorutils import random_web
from tkinter import Tk, Button
mgui = Tk()
mgui.geometry('150x28+400+200')
def rcolor():
rn = random_web()
print(rn) # for terminal watchers
cbutton.config(text=rn)
mgui.config(bg=rn)
cbutton = Button(text="Click", command=rcolor)
cbutton.pack()
mgui.mainloop()
I certainly hope that was helpful.
import secrets
# generate 4 sets of 2-digit hex chars for a color with transparency
rgba = f"#{secrets.token_hex(4)}" # example return: "#ffff0000"
# generate 3 sets of 2-digit hex chars for a non-alpha color
rgb = f"#{secrets.token_hex(3)}" # example return: "#ab12ce"
import random
def generate_color():
color = '#{:02x}{:02x}{:02x}'.format(*map(lambda x: random.randint(0, 255), range(3)))
return color
Basically, this will give you a hashtag, a randint that gets converted to hex, and a padding of zeroes.
from random import randint
color = '#{:06x}'.format(randint(0, 256**3))
#Use the colors wherever you need!
For generating random anything, take a look at the random module
I would suggest you use the module to generate a random integer, take it's modulo 2**24, and treat the top 8 bits as R, that middle 8 bits as G and the bottom 8 as B.
It can all be accomplished with div/mod or bitwise operations.
hex_digits = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
digit_array = []
for i in xrange(6):
digit_array.append(hex_digits[randint(0,15)])
joined_digits = ''.join(digit_array)
color = '#' + joined_digits
import random
def get_random_hex:
random_number = random.randint(0,16777215)
# convert to hexadecimal
hex_number = str(hex(random_number))
# remove 0x and prepend '#'
return'#'+ hex_number[2:]
Would like to improve upon this solution as I found that it could generate color codes that have less than 6 characters. I also wanted to generate a function that would create a list that can be used else where such as for clustering in matplotlib.
import random
def get_random_hex:
random_number = random.randint(0,16777215)
# convert to hexadecimal
hex_number = str(hex(random_number))
# remove 0x and prepend '#'
return'#'+ hex_number[2:]
My proposal is :
import numpy as np
def color_generator (no_colors):
colors = []
while len(colors) < no_colors:
random_number = np.random.randint(0,16777215)
hex_number = format(random_number, 'x')
if len(hex_number) == 6:
hex_number = '#'+ hex_number
colors.append (hex_number)
return colors
Here's a simple code that I wrote based on what hexadecimal color notations represent:
import random
def getRandomCol():
r = hex(random.randrange(0, 255))[2:]
g = hex(random.randrange(0, 255))[2:]
b = hex(random.randrange(0, 255))[2:]
random_col = '#'+r+g+b
return random_col
The '#' in the hexadecimal color code just represents that the number represented is just a hexadecimal number. What's important is the next 6 digits. Pairs of 2 digits in those 6 hexadecimal digits represent the intensity of RGB (Red, Green, and Blue) each. The intensity of each color ranges between 0-255 and a combination of different intensities of RGB produces different colors.
For example, in #ff00ff, the first ff is equivalent to 255 in decimal, the next 00 is equivalent to 0 in decimal, and the last ff is equivalent to 255 in decimal. Therefore, #ff00ff in hexadecimal color coding is equivalent to RGB(255, 0, 255).
With this concept, here's the explanation of my approach:
Generated intensities of random numbers for each of r, g
and b
Converted those intensities into hexadecimal
Ignored the first 2 characters of each hexadecimal value '0x'
Concatenated '#' with the hexadecimal values r, g and b
intensities.
Feel free to refer to this link if you wanna know more about how colors work: https://hackernoon.com/hex-colors-how-do-they-work-d8cb935ac0f
Cheers!
Hi, maybe i could help with the next function that generate random Hex colors :
from colour import Color
import random as random
def Hex_color():
L = '0123456789ABCDEF'
return Color('#'+ ''.join([random.choice(L) for i in range(6)][:]))
from random import randbytes
randbytes(3).hex()
output
f5f2c9
There are a lot of complex answers here, this is what I used for a code of mine using one import line and one line to get a random code:
import random
color = '#' + ''.join(random.choices('0123456789ABCDEF', k=6))
print(color)
The output will be something like:
#3F67CD
If you want to make a list of color values, let's say, of 10 random colors, you can do the following:
import random as r
hex_chars = '0123456789ABCDEF'
num_colors = 10
colors = ['#' + ''.join(r.choices(hex_chars, k=6)) for _ in range(num_colors)]
print(colors)
And the output will be a list containing ten different random colors:
['#3DBEA2', '#0B3B64', '#31D196', '#6A98C2', '#9C1712', '#73AFFE', '#9F5E0D', '#A2F07E', '#EB6407', '#7E8FB6']
I hope that helps!

Categories

Resources