Skip to content

Commit 455e658

Browse files
authored
Merge pull request #1 from luogu-dev/master
Update the new library
2 parents 7c3a4db + a918dca commit 455e658

30 files changed

+703
-515
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
config.py
2+
*.in
3+
*.out
24

35
# Created by .ignore support plugin (hsz.mobi)
46
### Python template

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: python
2+
python:
3+
- "2.7"
4+
- "3.5"
5+
- "3.6"
6+
- "pypy"
7+
- "pypy3"
8+
script: python unit_test.py
9+

LICENSE

Lines changed: 159 additions & 444 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
CYaRon: Yet Another Random Olympic-iNformatics test data generator
33

44
By Luogu
5-
5+
[![](https://travis-ci.org/luogu-dev/cyaron.svg?branch=master)](https://travis-ci.org/luogu-dev/cyaron)
66

77
你是否遇到以下情况:
88
- 希望在5分钟内写出一组随机数据
@@ -14,15 +14,18 @@ By Luogu
1414
- 建一个随机图(简单图或者非简单图,有向图或无向图,带权图或者无权图)
1515
- 建一个随机树(链状、随机树、或者菊花图,而且可以设定树的强弱)
1616
- 生成一组允许相同或者互相不同的多维向量(可以较快速度生成10^6组、范围到10^9的向量或者数列)
17+
- 根据函数解析式生成数列
18+
- 生成一些随机多边形,并且可以求面积、周长等
19+
- 从字典生成随机字符串、单词、句子、段落
1720

1821
**快速上手指南**
1922

2023
你可以下载github源代码 https://github.com/luogu-dev/cyaron ,或者`pip install cyaron`。在此之前,需要准备好python2/3。
2124

22-
暂时文档没有写好,之后将慢慢补充。请根据demo和源代码进行YY
25+
[文档](https://github.com/luogu-dev/cyaron/wiki/%E9%A6%96%E9%A1%B5)仍在建设中,尚不完整,之后将慢慢补充。请根据`examples`和源代码进行YY
2326

2427
首批贡献者 @fjzzq2002 @lin_toto @kkksc03
2528

2629
之后计划实现云Generator,即只需提供写好的python脚本以及std,上传到服务器,即可下载一个测试数据的压缩包,真正实现5分钟生成一个测试数据!
2730

28-
目前CYaRon的功能还比较初级,希望各位大佬一起来协助改进这个项目。希望这个项目可以帮助大家节省时间!
31+
目前CYaRon的功能还比较初级,希望各位大佬一起来协助改进这个项目。希望这个项目可以帮助大家节省时间!

cyaron/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
from .utils import *
1212
from .consts import *
1313
from .vector import Vector
14+
from .polygon import Polygon
1415
from random import randint, randrange, uniform, choice, random
1516

cyaron/graph.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def to_str(self, **kwargs):
5151
edge_buf = []
5252
for edge in self.iterate_edges():
5353
edge_buf.append(
54-
Edge(tmp[edge.start], tmp[edge.end], edge.weight))
54+
Edge(new_node_id[edge.start], new_node_id[edge.end], edge.weight))
5555
random.shuffle(edge_buf)
5656
for edge in edge_buf:
5757
if not self.directed and random.randint(0, 1) == 0:
@@ -74,7 +74,8 @@ def iterate_edges(self):
7474
"""
7575
for node in self.edges:
7676
for edge in node:
77-
yield edge
77+
if edge.end >= edge.start or self.directed:
78+
yield edge
7879

7980
def __add_edge(self, x, y, w):
8081
"""__add_edge(self, x, y, w) -> None
@@ -92,7 +93,6 @@ def add_edge(self, x, y, **kwargs):
9293
not directed means if you added the edge x->y, you would also add the edge y->x
9394
"""
9495
weight = kwargs.get("weight", 1)
95-
directed = kwargs.get("directed", True)
9696
self.__add_edge(x, y, weight)
9797
if not self.directed and x != y:
9898
self.__add_edge(y, x, weight)
@@ -145,7 +145,7 @@ def tree(point_count, chain=0, flower=0, **kwargs):
145145
"""
146146
directed = kwargs.get("directed", False)
147147
weight_limit = kwargs.get("weight_limit", (1, 1))
148-
if not isinstance(weight_limit, tuple):
148+
if not list_like(weight_limit):
149149
weight_limit = (1, weight_limit)
150150
weight_gen = kwargs.get(
151151
"weight_gen", lambda: random.randint(
@@ -193,7 +193,7 @@ def binary_tree(point_count, left=0, right=0, **kwargs):
193193
"""
194194
directed = kwargs.get("directed", False)
195195
weight_limit = kwargs.get("weight_limit", (1, 1))
196-
if not isinstance(weight_limit, tuple):
196+
if not list_like(weight_limit):
197197
weight_limit = (1, weight_limit)
198198
weight_gen = kwargs.get(
199199
"weight_gen", lambda: random.randint(
@@ -204,11 +204,11 @@ def binary_tree(point_count, left=0, right=0, **kwargs):
204204
if left + right > 1:
205205
raise Exception("left plus right must be smaller than 1")
206206

207-
can_left = {1}
208-
can_right = {1}
207+
can_left = set([1])
208+
can_right = set([1])
209209
graph = Graph(point_count, directed)
210210
for i in range(2, point_count + 1):
211-
edge_pos = random.uniform(0, 1)
211+
edge_pos = random.random()
212212
node = 0
213213
# Left
214214
if edge_pos < left or left + right < edge_pos <= (1.0 - left - right) / 2:
@@ -240,7 +240,7 @@ def graph(point_count, edge_count, **kwargs):
240240
"""
241241
directed = kwargs.get("directed", False)
242242
weight_limit = kwargs.get("weight_limit", (1, 1))
243-
if not isinstance(weight_limit, tuple):
243+
if not list_like(weight_limit):
244244
weight_limit = (1, weight_limit)
245245
weight_gen = kwargs.get(
246246
"weight_gen", lambda: random.randint(
@@ -250,9 +250,8 @@ def graph(point_count, edge_count, **kwargs):
250250
u = random.randint(1, point_count)
251251
v = random.randint(1, point_count)
252252
graph.add_edge(u, v, weight=weight_gen())
253-
return graph
254-
255-
# hack spfa (maybe?)
253+
return graph
254+
256255
@staticmethod
257256
def hack_spfa(point_count, **kwargs):
258257
"""hack_spfa(point_count, **kwargs) -> None
@@ -270,7 +269,7 @@ def hack_spfa(point_count, **kwargs):
270269
directed = kwargs.get("directed", False)
271270
extraedg = kwargs.get("extra_edge", 2)
272271
weight_limit = kwargs.get("weight_limit", (1, 1))
273-
if not isinstance(weight_limit, tuple):
272+
if not list_like(weight_limit):
274273
weight_limit = (1, weight_limit)
275274
weight_gen = kwargs.get(
276275
"weight_gen", lambda: random.randint(
@@ -280,7 +279,7 @@ def hack_spfa(point_count, **kwargs):
280279
graph = Graph(point_count, directed)
281280
if point_count % 2 == 1:
282281
point_to_skip = point_count / 2 + 1
283-
half = point_count / 2
282+
half = int(point_count / 2)
284283

285284
for i in range(1, half):
286285
(x, y) = (i, i + 1)
@@ -298,4 +297,5 @@ def hack_spfa(point_count, **kwargs):
298297
u = random.randint(1, point_count)
299298
v = random.randint(1, point_count)
300299
graph.add_edge(u, v, weight=weight_gen())
300+
301301
return graph

cyaron/io.py

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from .utils import *
12
import subprocess
23

34

@@ -31,16 +32,20 @@ def __init__(self, *args, **kwargs):
3132

3233
input_suffix = kwargs.get("input_suffix", ".in")
3334
output_suffix = kwargs.get("output_suffix", ".out")
35+
disable_output = kwargs.get("disable_output", False)
3436
self.input_filename = filename_prefix + input_suffix
35-
self.output_filename = filename_prefix + output_suffix
37+
self.output_filename = filename_prefix + output_suffix if not disable_output else None
38+
elif len(args) == 1:
39+
self.input_filename = args[0]
40+
self.output_filename = None
3641
elif len(args) == 2:
3742
self.input_filename = args[0]
3843
self.output_filename = args[1]
3944
else:
4045
raise Exception("Invalid argument count")
4146

4247
self.input_file = open(self.input_filename, 'w')
43-
self.output_file = open(self.output_filename, 'w')
48+
self.output_file = open(self.output_filename, 'w') if self.output_filename else None
4449

4550
def __del__(self):
4651
"""__del__(self) -> None
@@ -52,30 +57,53 @@ def __del__(self):
5257
except Exception:
5358
pass
5459

60+
def __enter__(self):
61+
return self
62+
63+
def __exit__(self, exc_type, exc_val, exc_tb):
64+
"""__del__(self) -> None
65+
Exit the context of the IO object and close the input file and the output file
66+
"""
67+
try:
68+
self.input_file.close()
69+
self.output_file.close()
70+
except Exception:
71+
pass
72+
5573
@staticmethod
56-
def __write(file, *args):
57-
"""__write(file, *args) -> None
74+
def __write(file, *args, **kwargs):
75+
"""__write(file, *args, **kwargs) -> None
5876
Write every element in *args into file. If the element isn't "\n", insert a space. It will convert every element into str
5977
file file -> the file object to write
78+
**kwargs:
79+
str separator = " " -> a string used to separate every element
6080
"""
81+
separator = kwargs.get("separator", " ")
6182
for arg in args:
62-
file.write(str(arg))
63-
if arg != "\n":
64-
file.write(" ")
83+
if list_like(arg):
84+
IO.__write(file, *arg, **kwargs)
85+
else:
86+
file.write(str(arg))
87+
if arg != "\n":
88+
file.write(separator)
6589

66-
def write(self, *args):
67-
"""write(self, *args) -> None
90+
def input_write(self, *args, **kwargs):
91+
"""input_write(self, *args, **kwargs) -> None
6892
Write every element in *args into the input file. Splits with spaces. It will convert every element into string
93+
**kwargs:
94+
str separator = " " -> a string used to separate every element
6995
"""
70-
IO.__write(self.input_file, *args)
96+
IO.__write(self.input_file, *args, **kwargs)
7197

72-
def writeln(self, *args):
73-
"""writeln(self, *args) -> None
98+
def input_writeln(self, *args, **kwargs):
99+
"""input_writeln(self, *args, **kwargs) -> None
74100
Write every element in *args into the input file and turn to a new line. Splits with spaces. It will convert every element into string
101+
**kwargs:
102+
str separator = " " -> a string used to separate every element
75103
"""
76104
args = list(args)
77105
args.append("\n")
78-
self.write(*args)
106+
self.input_write(*args, **kwargs)
79107

80108
def output_gen(self, shell_cmd):
81109
"""output_gen(self, shell_cmd) -> None
@@ -84,20 +112,24 @@ def output_gen(self, shell_cmd):
84112
"""
85113
self.input_file.close()
86114
with open(self.input_filename, 'r') as f:
87-
self.output_file.write(subprocess.check_output(shell_cmd, shell=True, stdin=f))
115+
self.output_file.write(subprocess.check_output(shell_cmd, shell=True, stdin=f).decode('ascii'))
88116

89117
self.input_file = open(self.input_filename, 'a')
90118

91-
def output_write(self, *args):
92-
"""output_write(self, *args) -> None
119+
def output_write(self, *args, **kwargs):
120+
"""output_write(self, *args, **kwargs) -> None
93121
Write every element in *args into the output file. Splits with spaces. It will convert every element into string
122+
**kwargs:
123+
str separator = " " -> a string used to separate every element
94124
"""
95-
IO.__write(self.output_file, *args)
125+
IO.__write(self.output_file, *args, **kwargs)
96126

97-
def output_writeln(self, *args):
98-
"""output_writeln(self, *args) -> None
127+
def output_writeln(self, *args, **kwargs):
128+
"""output_writeln(self, *args, **kwargs) -> None
99129
Write every element in *args into the output file and turn to a new line. Splits with spaces. It will convert every element into string
130+
**kwargs:
131+
str separator = " " -> a string used to separate every element
100132
"""
101133
args = list(args)
102134
args.append("\n")
103-
self.output_write(*args)
135+
self.output_write(*args, **kwargs)

0 commit comments

Comments
 (0)