Neste artigo, não nos deteremos nos aspectos jurídicos das notificações enviadas sobre um CFC, sobre a participação em um CFC, consideraremos o lado técnico da questão.
Sem dúvida, se a holding em questão se apresenta como estruturas simples do tipo LLC-> KIK-> Russo, então é impraticável construir algo aqui com o envolvimento de uma máquina, é outra questão se a estrutura se ramifica, dobra e não há número desses entrelaçamentos.
Vamos dar uma olhada em várias soluções gráficas existentes que tornarão seu trabalho mais fácil.
Para facilitar a visualização, o notebook jupyter e o ambiente python serão usados.
Networkx
Esta solução é a mais antiga das apresentadas e não pode orgulhar-se da sua interactividade. Existe o mesmo artigo antigo sobre este pacote no Habré.
Porém, o antigo não significa ruim, e esta opção é uma das mais bem-sucedidas tanto em termos de desenho quanto de computação.
Instale e importe o módulo via jupyter:
!pip install networkx
import networkx as nx
Também importamos outros anúncios. módulos que o ajudarão a desenhar formas:
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams.update({
'figure.figsize': (7.5, 7.5),
'axes.spines.right': False,
'axes.spines.left': False,
'axes.spines.top': False,
'axes.spines.bottom': False})
Vamos construir a primeira rede usando networkx:
from pathlib import Path
data_dir = Path('.') / 'data'
# Read edge list
G = nx.read_edgelist('example.edgelist')
# Draw network
#pos = nx.spring_layout(G)
pos = nx.spectral_layout(G)
#pos = nx.planar_layout(G)
nx.draw_networkx(G, pos)
plt.gca().margins(0.15, 0.15)
Eis o que aconteceu:
como você pode ver, Ivanov possui dois CFCs, que, por sua vez, possuem entidades legais russas. por pessoas.
Vamos analisar o código acima.
Importamos o módulo e especificamos onde leremos os dados no disco de:
from pathlib import Path
data_dir = Path('.') / 'data'
O diretório atual foi considerado 'example.edgelist':
G = nx.read_edgelist('example.edgelist')
* example.edgelist é um arquivo de texto simples como este:
# source target
1
2
1 2
1 _
2 _
Os valores são registrados por alguém com um espaço entre eles.
Em seguida, determinamos como será a aparência da rede:
pos = nx.spectral_layout(G)
Se mudarmos para pos = nx.spring_layout (G), então ele assumirá a forma:
E este arranjo, curiosamente, é mais adequado para estruturas maiores.
Por fim, desenhamos a rede, marcando os recuos:
nx.draw_networkx(G, pos)
plt.gca().margins(0.15, 0.15)
É fácil salvar uma imagem:
plt.savefig('plot.png')
Como desenhar um segmento em networkx
#
H = G.subgraph(['', '1', '_'])
plt.subplot(212)
print(":")
nx.draw_networkx(H)
Não
recuamos aqui, e os nomes "à esquerda": Networkx opera com os conceitos de nós e links entre eles. Em nossa situação, os nós são Ivanov, KIK1, KIK2, Romashka_OOO, Bucket_AO. E os links são os que estão no arquivo example.edgelist.
Você pode ver os dois simplesmente referindo-se aos métodos G.nodes e G.edges:
Gráfico direcional em networkx (lista de arestas direcionadas)
Vamos esclarecer um pouco a rede construída, adicionar setas:
# Read edge list
G = nx.read_edgelist(
str('example.edgelist'),
create_using=nx.DiGraph)
pos = nx.spectral_layout(G)
# Draw network
nx.draw_networkx(G, pos, arrowsize=20)
plt.gca().margins(0.15, 0.15)
Pequenas mudanças tornaram possível pintar uma imagem mais clara de quem é o dono de quem:
No código, como você pode ver, as mudanças são mínimas.
O próximo passo é construir um gráfico onde o tamanho dos pacotes de propriedade será visível.
Para fazer isso, você precisa se familiarizar com o conceito de peso (peso) é o terceiro parâmetro principal com o qual o networkx pode trabalhar. Para incluí-lo no trabalho, você precisa adicionar esses mesmos pesos a um arquivo de texto, por exemplo:
# source target
1 100
2 100
1 2 50
1 _ 100
2 _ 100
Agora vamos reconstruir a rede usando os pesos e designá-los no gráfico:
# Read edge list
G = nx.read_weighted_edgelist(
str('example2.edgelist'))
# Extract weights
weights = [d['weight'] for s, t, d in G.edges(data=True)]
nx.draw_networkx(G,pos)
labels = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
plt.gca().margins(0.15, 0.15)
* example2.edgelist é o arquivo gerado acima com pesos.
Temos a seguinte imagem:
Quem possui quem e como, networkx
Agora, como advogados-programadores, precisamos entender em que sequência e em que quantidade Ivanov possui, por exemplo, Bucket_AO, e se ele o possui. Isso é necessário para determinar o fato da propriedade na holding ramificada e todas as cadeias para o LLC alvo (JSC), para que posteriormente essas cadeias possam ser registradas na notificação CFC.
Com o networkx, você pode fazer isso da seguinte maneira:
list(nx.all_simple_paths(G,'', '_'))
O primeiro argumento é o nó proprietário, o segundo é o nó para o qual construiremos caminhos.
Usando este método, você pode ver que Bucket_AO de Ivanov pertence às seguintes cadeias:
[['', '1', '2', '_'], ['', '2', '_']]
Isso é confirmado graficamente.
Você pode descobrir a parcela de propriedade multiplicando os pesos entre os nós correspondentes: 1 * 0,5 * 1 = 0,5, 1 * 1 = 1. Participação de mais de 25%, notificação deve ser enviada.
No código, a multiplicação é feita com as seguintes muletas (um método mais elegante ainda não foi encontrado):
x=0
b=0
c=[]
for i in list(nx.all_simple_paths(G,'', '_')):
for a in i:
if x>len(i)-2:
pass
else:
b=int(nx.bidirectional_dijkstra(G, i[x],i[x+1])[0])#
x+=1
c.append(b/100)
print(c)
import numpy as np
print(np.prod(c))
x=0
b=0
c=[]
for i in list(nx.all_shortest_paths(G,'', '_')):
for a in i:
if x>len(i)-2:
pass
else:
b=int(nx.bidirectional_dijkstra(G, i[x],i[x+1])[0])#
x+=1
c.append(b/100)
print(c)
import numpy as np
print(np.prod(c))
No primeiro caso, ele exibirá uma fração de 0,5, no segundo 1.
Que outras opções de visualização estão disponíveis? Por exemplo, Netwulf.
Netwulf
A documentação está aqui .
A própria rede é interativa, esta é sua principal vantagem. Depois de instalar o pacote python, vamos construir a rede:
import netwulf as nw
plt.figure(figsize=(200,200))
G = nx.read_weighted_edgelist(str('example2.edgelist'),create_using=nx.DiGraph)
pos = nx.spring_layout(G)
nw.visualize(G)
Após executar o código, o jupyter congela e em uma janela adicional do navegador que se abre, você pode ver o resultado:
No lado direito do painel, você pode ver as opções, alterando o que afeta a rede construída online.
A desvantagem deste pacote é que ainda não é possível mostrar os pesos e setas entre os nós, mas os autores prometeram refiná-lo.
* para voltar ao jupyter você precisa clicar na opção "postar para python":
Outra boa opção para tal visualização para python é o projeto webweb jovem.
Webweb
A documentação está aqui .
A rede é construída de maneira semelhante:
from webweb import Web
web = Web(title='kitchen_sink')
web.display.networkName = 'tree'
web.display.networkLayer = 2
web.display.colorBy = 'ring'
web.display.sizeBy = 'degree'
web.display.gravity = .3
web.display.charge = 30
web.display.linkLength = 15
web.display.colorPalette = 'Greens'
web.display.scaleLinkOpacity = False
web.display.scaleLinkWidth = True
from pathlib import Path
data_dir = Path('.') / 'data'
# Read edge list
G = nx.read_edgelist('example.edgelist',create_using=nx.DiGraph)
plt.figure(figsize=(200,200))
# Draw network
pos = nx.spring_layout(G)
Web(list(G.edges)).show()
Das vantagens claras sobre o netwulf: a capacidade de destacar nós-chave com cores, pesquisa de texto para nós com destaque na rede: Em
resumo, podemos dizer que os descendentes em desenvolvimento de networkx - netwulf e webweb são bons para construir uma imagem rápida da estrutura de uma pequena propriedade. Ambos os módulos têm um modo de congelamento para congelar nós que ficam juntos em uma pilha devido à interatividade do gráfico. Porém, mesmo utilizando-os, não é fácil trabalhar com estruturas de grande escala onde o número de nós é superior a 200.
"Pedestal" do Ministério das Finanças, propriedade cruzada e anelar
Tudo seria muito bom na construção de tais estruturas, se não fosse por uma coisa que estraga o quadro todo. Isto, no entanto, reside no facto de as participações da empresa serem proprietárias através de outras pessoas jurídicas. faces e isso é chamado de propriedade cruzada ou anel.
Nas fotos em cartas do Ministério das Finanças (por exemplo, de 02.07.2013 -4-13 / 11912) é assim.
Propriedade cruzada: em forma de anel
:
Vamos ver como o networkx define os links para o esquema de propriedade cruzada da participação de D em B.
Vamos criar um edgelist com links:
# source target
D B 45
B A 40
A B 55
E A 60
Tendo construído uma rede com pesos, você pode ver que o feedback entre A e B não é refletido:
Pode ser visto se você construir uma rede sem pesos, com setas:
E quanto aos cálculos? Qual é a participação cumulativa de D em B?
Tudo parece transparente aqui, 45%
E o networkx dá a lista de comandos (nx.all_simple_paths (G, 'D', 'B')):
[['D', 'B']]
Mas nem tudo é tão simples.
O Ministério da Fazenda afirma que a participação total de D em B é determinada pela fórmula:
E será de 57,69%.
O que fazer? networkx é impotente?
De forma alguma, o networkx revelará tais situações, mas a fórmula de cálculo será diferente, de acordo com a “letra da lei”.
Este problema pode ser parcialmente resolvido adicionando entradas
AA
BB ao edgelist
Além disso, com a lista de comandos (nx.nodes_with_selfloops (G)), você pode ver os nós com participação neles, mas isso ainda não é levado em consideração ao determinar os caminhos de D para B.
download do notebook jupyter - aqui .