0

I am trying to create a specific output pattern for a textfile I wanted to later load into C++. I wrote a file in Python that creates random coordinates and movement values in a circle. The output is supposed to have the output:


   Place_1 Place_2 Place_3 Movement_1 Movement_2 Movement_3\n

   Place_1 Place_2 Place_3 Movement_1 Movement_2 Movement_3\n

   Place_1 Place_2 Place_3 Movement_1 Movement_2 Movement_3

The Code is use is

import numpy as np
file = open('log.txt', 'a')


def f(n, center, radius, ecc):
  pos = np.zeros((n,6))
  r = ecc * radius
  for i in range(n):
    while 1:
        x_1 = -1 + 2 * np.random.rand(1)
        x_2 = -1 + 2 * np.random.rand(1)
        if (x_1*x_1 + x_2*x_2)<1 :
            pos[i,0] = center[0] + r * 2 * x_1 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
            pos[i,1] = center[1] + r * 2 * x_2 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
            pos[i,2] = center[2] + r * (1 - 2 * (x_1*x_1 + x_2*x_2))
            pos[i,3] = (-1 + 2 * np.random.rand(1))
            pos[i,4] = (-1 + 2 * np.random.rand(1))
            pos[i,5] = (-1 + 2 * np.random.rand(1))
            break
    string = str(pos[i,:]).strip('[]').rstrip('\n')
    file.write(string)
  return

f(10000, np.array((127,127,127)), 92, 0.9)

file.close()

The log I create is however very badly formated. How can I get the required format?

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
Otrbit
  • 15
  • 5
  • Why are you converting the list to a string using `str(np.array)`? Likely you'd be best to use python's [`f-strings`](https://realpython.com/python-f-strings/) – Joshua Voskamp Nov 09 '21 at 21:26
  • Using f'{pos[i,:]}' I get the output ``` [ 2.03736833e+02 1.14369585e+02 1.55421313e+02 -1.34950352e-01 -9.72404614e-01 -2.09317199e-01][1.49366346e+02 2.06721909e+02 1.27061388e+02 8.06931664e-02 7.56406688e-01 8.88693928e-01][ 1.34785976e+02 2.08259133e+02 1.40862604e+02 7.38588837e-01 -3.73978657e-01 -6.24811099e-02][ 1.73819151e+02 1.15782307e+02 5.96355398e+01 7.02889793e-01 -1.00268889e-01 -2.40929366e-01][ 7.93221415e+01 1.31692531e+02 5.94674748e+01 3.73394744e-01 -2.16969418e-02 -4.58853325e-01][ 9.16926315e+01 1.45733283e+02 1.99514094e+02 3.65330619 ``` – Otrbit Nov 09 '21 at 21:30
  • This sadly still doesnt fullfill the necessary format... – Otrbit Nov 09 '21 at 21:31
  • you'll need to appropriately format the list beyond just spitting the whole thing out; am working on a solution. – Joshua Voskamp Nov 09 '21 at 21:32
  • Luckily I already got an Solution from Tim Roberts, but still thank you! – Otrbit Nov 09 '21 at 21:35

3 Answers3

2

You're going to a lot of trouble here that you don't need. This seems to solve the problem, simply.

import numpy as np
file = open('log.txt', 'a')

def f(n, center, radius, ecc):
    r = ecc * radius
    for i in range(n):
        while 1:
            pos = [0]*6
            x_1 = -1 + 2 * np.random.rand(1)[0]
            x_2 = -1 + 2 * np.random.rand(1)[0]
            if (x_1*x_1 + x_2*x_2) < 1:
                pos[0] = center[0] + r * 2 * x_1 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
                pos[1] = center[1] + r * 2 * x_2 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
                pos[2] = center[2] + r * (1 - 2 * (x_1*x_1 + x_2*x_2))
                pos[3] = (-1 + 2 * np.random.rand(1)[0])
                pos[4] = (-1 + 2 * np.random.rand(1)[0])
                pos[5] = (-1 + 2 * np.random.rand(1)[0])
                break
        print(*pos, file=file)

f(10000, np.array((127,127,127)), 92, 0.9)

file.close()

A solution without numpy:

import math
import random
file = open('log.txt', 'a')

def f(n, center, radius, ecc):
    r = ecc * radius
    for _ in range(n):
        pos = [0]*6
        while 1:
            x_1 = 2 * random.random() - 1
            x_2 = 2 * random.random() - 1
            vector = x_1*x_1 + x_2*x_2
            if vector < 1:
                break
        pos[0] = center[0] + r * 2 * x_1 * math.sqrt(1 - vector)
        pos[1] = center[1] + r * 2 * x_2 * math.sqrt(1 - vector)
        pos[2] = center[2] + r * (1 - 2 * vector)
        pos[3] = 2 * random.random() -1
        pos[4] = 2 * random.random() -1
        pos[5] = 2 * random.random() -1
        print(*pos, file=file)

f(10000, (127,127,127), 92, 0.9)

file.close()
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
  • This worked! Thanks a lot! – Otrbit Nov 09 '21 at 21:34
  • And unless you're using it for other things, you don't need numpy here at all. `random.random` would serve the purpose nicely. – Tim Roberts Nov 09 '21 at 21:36
  • @TimRoberts I'd argue using `np.savetxt` would be more efficient; am happy to be shown incorrect, however. – Joshua Voskamp Nov 09 '21 at 21:36
  • 1
    The only downside is that you have to construct the entire array in memory before writing it. I'm writing each line then discarding the data. It depends on the use case. If he doesn't need the resulting array, there's no need to build it. – Tim Roberts Nov 09 '21 at 21:40
  • 1
    Would also suggest computing `(x_1*x_1 + x_2*x_2)` once, and using it four times in the calculation `if (value) < 1, pos[0,1,2]`, fwiw – Joshua Voskamp Nov 09 '21 at 21:42
1

Use np.savetxt:

import numpy as np

def f(n, center, radius, ecc):
  pos = np.zeros((n,6))
  r = ecc * radius
  for i in range(n):
    while 1:
        x_1 = -1 + 2 * np.random.rand(1)
        x_2 = -1 + 2 * np.random.rand(1)
        if (x_1*x_1 + x_2*x_2)<1 :
            pos[i,0] = center[0] + r * 2 * x_1 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
            pos[i,1] = center[1] + r * 2 * x_2 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
            pos[i,2] = center[2] + r * (1 - 2 * (x_1*x_1 + x_2*x_2))
            pos[i,3] = (-1 + 2 * np.random.rand(1))
            pos[i,4] = (-1 + 2 * np.random.rand(1))
            pos[i,5] = (-1 + 2 * np.random.rand(1))
            break
  np.savetxt('file.txt',pos,delimiter=';')
  return

f(100, np.array((127,127,127)), 92, 0.9)
Joshua Voskamp
  • 1,855
  • 1
  • 10
  • 13
-1

For the formatting issue you can make the coordinates into characters (What I mean is that turn coordinates into a character that would be printed like _ or / something like that) Also you can put empty space in a print like print(" Hello.") also to go to a different line in the console do print("\n Hello."). This probably was not what you were looking for but I hope this somewhat helps.

Viridian
  • 25
  • 3
  • This answer is totally unhelpful. – Tim Roberts Nov 09 '21 at 21:33
  • While I am happy for the help, I dont quite get the suggestion here. How would this solve the output formating problem? Sadly I dont understand your solution-idea. – Otrbit Nov 09 '21 at 21:33
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Tyler2P Nov 09 '21 at 21:50
  • In the future, if you have to write "this probably was not what you were looking for", then you should not post it. Answers on StackOverflow are expected to be high quality, even more so than the questions. – Tim Roberts Nov 09 '21 at 21:52