@@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""Sample to test or-tools installation."""
|
||||
|
||||
import ortools
|
||||
|
||||
# from ortools.algorithms import knapsack_solver
|
||||
|
||||
@@ -180,7 +180,7 @@ def aggregate_item_collections_optimally(
|
||||
|
||||
|
||||
def get_optimal_schedule(
|
||||
demand: list[tuple[float, str, int]]
|
||||
demand: list[tuple[float, str, int]],
|
||||
) -> list[tuple[int, list[tuple[int, str]]]]:
|
||||
"""Computes the optimal schedule for the installation input.
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ be as close to the average as possible.
|
||||
Furthermore, if one color is an a group, at least k items with this color must
|
||||
be in that group.
|
||||
"""
|
||||
|
||||
from typing import Dict, Sequence
|
||||
|
||||
from absl import app
|
||||
|
||||
@@ -29,6 +29,7 @@ import math
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
|
||||
from google.protobuf import text_format
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
@@ -81,7 +82,7 @@ SAMPLE_SHIFTS_TINY = [
|
||||
[25, "15:40", "15:56", 940, 956, 16],
|
||||
[26, "15:58", "16:45", 958, 1005, 47],
|
||||
[27, "16:04", "17:30", 964, 1050, 86],
|
||||
] # yapf:disable
|
||||
]
|
||||
|
||||
SAMPLE_SHIFTS_SMALL = [
|
||||
#
|
||||
@@ -143,7 +144,7 @@ SAMPLE_SHIFTS_SMALL = [
|
||||
[47, "18:34", "19:58", 1114, 1198, 84],
|
||||
[48, "19:56", "20:34", 1196, 1234, 38],
|
||||
[49, "20:05", "20:48", 1205, 1248, 43],
|
||||
] # yapf:disable
|
||||
]
|
||||
|
||||
SAMPLE_SHIFTS_MEDIUM = [
|
||||
[0, "04:30", "04:53", 270, 293, 23],
|
||||
@@ -346,7 +347,7 @@ SAMPLE_SHIFTS_MEDIUM = [
|
||||
[197, "00:02", "00:12", 1442, 1452, 10],
|
||||
[198, "00:07", "00:39", 1447, 1479, 32],
|
||||
[199, "00:25", "01:12", 1465, 1512, 47],
|
||||
] # yapf:disable
|
||||
]
|
||||
|
||||
SAMPLE_SHIFTS_LARGE = [
|
||||
[0, "04:18", "05:00", 258, 300, 42],
|
||||
@@ -1705,7 +1706,7 @@ SAMPLE_SHIFTS_LARGE = [
|
||||
[1353, "00:47", "01:26", 1487, 1526, 39],
|
||||
[1354, "00:54", "01:04", 1494, 1504, 10],
|
||||
[1355, "00:57", "01:07", 1497, 1507, 10],
|
||||
] # yapf:disable
|
||||
]
|
||||
|
||||
|
||||
def bus_driver_scheduling(minimize_drivers: bool, max_num_drivers: int) -> int:
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Use CP-SAT to solve a simple cryptarithmetic problem: SEND+MORE=MONEY.
|
||||
"""
|
||||
"""Use CP-SAT to solve a simple cryptarithmetic problem: SEND+MORE=MONEY."""
|
||||
|
||||
from absl import app
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
@@ -69,7 +69,7 @@ def main(_) -> None:
|
||||
branches = collector.Branches(i)
|
||||
failures = collector.Failures(i)
|
||||
print(
|
||||
("Solution #%i: value = %i, failures = %i, branches = %i," "time = %i ms")
|
||||
"Solution #%i: value = %i, failures = %i, branches = %i,time = %i ms"
|
||||
% (i, obj_value, failures, branches, time)
|
||||
)
|
||||
time = solver.WallTime()
|
||||
|
||||
@@ -24,6 +24,7 @@ see: https://en.wikipedia.org/wiki/Golomb_ruler
|
||||
"""
|
||||
|
||||
from typing import Sequence
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from google.protobuf import text_format
|
||||
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ from typing import Dict, Sequence
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
|
||||
from google.protobuf import text_format
|
||||
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
"""Test linear sum assignment on a 4x4 matrix.
|
||||
|
||||
Example taken from:
|
||||
http://www.ee.oulu.fi/~mpa/matreng/eem1_2-1.htm with kCost[0][1]
|
||||
modified so the optimum solution is unique.
|
||||
Example taken from:
|
||||
http://www.ee.oulu.fi/~mpa/matreng/eem1_2-1.htm with kCost[0][1]
|
||||
modified so the optimum solution is unique.
|
||||
"""
|
||||
|
||||
from typing import Sequence
|
||||
@@ -28,7 +28,12 @@ def run_assignment_on_4x4_matrix():
|
||||
"""Test linear sum assignment on a 4x4 matrix."""
|
||||
num_sources = 4
|
||||
num_targets = 4
|
||||
cost = [[90, 76, 75, 80], [35, 85, 55, 65], [125, 95, 90, 105], [45, 110, 95, 115]]
|
||||
cost = [
|
||||
[90, 76, 75, 80],
|
||||
[35, 85, 55, 65],
|
||||
[125, 95, 90, 105],
|
||||
[45, 110, 95, 115],
|
||||
]
|
||||
expected_cost = cost[0][3] + cost[1][2] + cost[2][1] + cost[3][0]
|
||||
|
||||
assignment = linear_sum_assignment.SimpleLinearSumAssignment()
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"""Maximize the number of valid combinations of Boolean variables."""
|
||||
|
||||
from typing import Sequence
|
||||
|
||||
from absl import app
|
||||
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
@@ -20,6 +20,7 @@ visit all boxes in order, and walk on each block in a 4x4x4 map exactly once.
|
||||
Admissible moves are one step in one of the 6 directions:
|
||||
x+, x-, y+, y-, z+(up), z-(down)
|
||||
"""
|
||||
|
||||
from typing import Dict, Sequence, Tuple
|
||||
|
||||
from absl import app
|
||||
|
||||
@@ -18,6 +18,7 @@ import time
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
_SIZE = flags.DEFINE_integer("size", 8, "Number of queens.")
|
||||
|
||||
@@ -18,6 +18,7 @@ from collections.abc import Sequence
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
|
||||
|
||||
@@ -52,7 +52,12 @@ def min_cost_flow_api():
|
||||
print("MinCostFlow on 4x4 matrix.")
|
||||
num_sources = 4
|
||||
num_targets = 4
|
||||
costs = [[90, 75, 75, 80], [35, 85, 55, 65], [125, 95, 90, 105], [45, 110, 95, 115]]
|
||||
costs = [
|
||||
[90, 75, 75, 80],
|
||||
[35, 85, 55, 65],
|
||||
[125, 95, 90, 105],
|
||||
[45, 110, 95, 115],
|
||||
]
|
||||
expected_cost = 275
|
||||
smcf = min_cost_flow.SimpleMinCostFlow()
|
||||
for source in range(0, num_sources):
|
||||
|
||||
@@ -27,9 +27,9 @@ from absl import app
|
||||
from absl import flags
|
||||
|
||||
from google.protobuf import text_format
|
||||
from ortools.sat.python import cp_model
|
||||
from ortools.scheduling import rcpsp_pb2
|
||||
from ortools.scheduling.python import rcpsp
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
_INPUT = flags.DEFINE_string("input", "", "Input file to parse and solve.")
|
||||
_OUTPUT_PROTO = flags.DEFINE_string(
|
||||
|
||||
@@ -18,7 +18,6 @@ import math
|
||||
from typing import Sequence
|
||||
from absl import app
|
||||
from absl import flags
|
||||
|
||||
from google.protobuf import text_format
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import time
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
|
||||
from google.protobuf import text_format
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import random
|
||||
from typing import Sequence
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
|
||||
@@ -27,7 +28,9 @@ _GRID_SIZE = flags.DEFINE_integer("grid_size", 20, "Size of the grid where nodes
|
||||
_PROFIT_RANGE = flags.DEFINE_integer("profit_range", 50, "Range of profit.")
|
||||
_SEED = flags.DEFINE_integer("seed", 0, "Random seed.")
|
||||
_PARAMS = flags.DEFINE_string(
|
||||
"params", "num_search_workers:16, max_time_in_seconds:5", "Sat solver parameters."
|
||||
"params",
|
||||
"num_search_workers:16, max_time_in_seconds:5",
|
||||
"Sat solver parameters.",
|
||||
)
|
||||
_PROTO_FILE = flags.DEFINE_string(
|
||||
"proto_file", "", "If not empty, output the proto to this file."
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# [START program]
|
||||
# [START import]
|
||||
from ortools.set_cover.python import set_cover
|
||||
|
||||
# [END import]
|
||||
|
||||
|
||||
|
||||
@@ -111,7 +111,10 @@ if __name__ == "__main__":
|
||||
"-l",
|
||||
"--log",
|
||||
type="string",
|
||||
help="Available levels are CRITICAL (3), ERROR (2), WARNING (1), INFO (0), DEBUG (-1)",
|
||||
help=(
|
||||
"Available levels are CRITICAL (3), ERROR (2), WARNING (1), INFO (0),"
|
||||
" DEBUG (-1)"
|
||||
),
|
||||
default="INFO",
|
||||
)
|
||||
options, args = parser.parse_args()
|
||||
|
||||
@@ -36,186 +36,182 @@ import sys
|
||||
|
||||
|
||||
class DoxygenFormatter:
|
||||
"""Transforms lines of a source file to make them Doxygen-friendly."""
|
||||
"""Transforms lines of a source file to make them Doxygen-friendly."""
|
||||
|
||||
ANYWHERE = 'anywhere'
|
||||
COMMENT = 'comment'
|
||||
ANYWHERE = "anywhere"
|
||||
COMMENT = "comment"
|
||||
|
||||
def __init__(self, outfile):
|
||||
# The file-like object to which we will write lines.
|
||||
self.out = outfile
|
||||
def __init__(self, outfile):
|
||||
# The file-like object to which we will write lines.
|
||||
self.out = outfile
|
||||
|
||||
# A buffer for storing empty lines which we can use later if we need to
|
||||
# retroactively insert markup without causing line number offset problems.
|
||||
self.empty_line_buffer = []
|
||||
# A buffer for storing empty lines which we can use later if we need to
|
||||
# retroactively insert markup without causing line number offset problems.
|
||||
self.empty_line_buffer = []
|
||||
|
||||
# Whether we are currently inside an indented code block.
|
||||
self.in_code_block = False
|
||||
# Whether we are currently inside an indented code block.
|
||||
self.in_code_block = False
|
||||
|
||||
self.CompileExpressions()
|
||||
self.CompileExpressions()
|
||||
|
||||
def CompileExpressions(self):
|
||||
"""Pre-compiles frequently used regexps for improved performance.
|
||||
def CompileExpressions(self):
|
||||
"""Pre-compiles frequently used regexps for improved performance.
|
||||
|
||||
The regexps are arranged as a list of 3-tuples, where the second value is
|
||||
the replacement string (which may include backreferences) and the third
|
||||
value is one of the context constants ANYWHERE or COMMENT. This is a list
|
||||
of tuples instead of a dictionary because order matters: earlier regexps
|
||||
will be applied first, and the resulting text (not the original) will be
|
||||
what is seen by subsequent regexps.
|
||||
"""
|
||||
self.comment_regex = re.compile(r'^\s*//')
|
||||
The regexps are arranged as a list of 3-tuples, where the second value is
|
||||
the replacement string (which may include backreferences) and the third
|
||||
value is one of the context constants ANYWHERE or COMMENT. This is a list
|
||||
of tuples instead of a dictionary because order matters: earlier regexps
|
||||
will be applied first, and the resulting text (not the original) will be
|
||||
what is seen by subsequent regexps.
|
||||
"""
|
||||
self.comment_regex = re.compile(r"^\s*//")
|
||||
|
||||
self.substitutions = [
|
||||
# Remove copyright lines.
|
||||
(re.compile(r'^\s*//\s*[Cc]opyright.*Google.*'), r'', self.ANYWHERE),
|
||||
self.substitutions = [
|
||||
# Remove copyright lines.
|
||||
(re.compile(r"^\s*//\s*[Cc]opyright.*Google.*"), r"", self.ANYWHERE),
|
||||
# Remove any comment lines that consist of only punctuation (banners).
|
||||
# We only allow a maximum of two spaces before the punctuation so we
|
||||
# don't accidentally get rid of code examples with bare braces and
|
||||
# whatnot.
|
||||
(re.compile(r"(^\s*)//\s{0,2}[-=#/]+$"), r"\1//\n", self.ANYWHERE),
|
||||
# If we find something that looks like a list item that is indented four
|
||||
# or more spaces, pull it back to the left so doxygen's Markdown engine
|
||||
# doesn't treat it like a code block.
|
||||
(re.compile(r"(^\s*)//\s{4,}([-\d*].*)"), r"\1 \2", self.COMMENT),
|
||||
# Replace TODO(user) in a comment with @todo (someone)
|
||||
(re.compile(r"TODO"), r"@todo ", self.COMMENT),
|
||||
# Replace leading 'Note:' or 'Note that' in a comment with @note
|
||||
(
|
||||
re.compile(r"(\/\/\s+)Note(?:\:| that)", re.I),
|
||||
r"\1@note",
|
||||
self.COMMENT,
|
||||
),
|
||||
# Replace leading 'Warning:' in a comment with @warning
|
||||
(re.compile(r"(\/\/\s+)Warning:", re.I), r"\1@warning", self.COMMENT),
|
||||
# Replace leading 'Deprecated' in a comment with @deprecated
|
||||
(
|
||||
re.compile(r"(\/\/\s+)Deprecated[^\w\s]*", re.I),
|
||||
r"\1@deprecated",
|
||||
self.COMMENT,
|
||||
),
|
||||
# Replace pipe-delimited parameter names with backtick-delimiters
|
||||
(re.compile(r"\|(\w+)\|"), r"`\1`", self.COMMENT),
|
||||
# Convert standalone comment lines to Doxygen style.
|
||||
(re.compile(r"(^\s*)//(?=[^/])"), r"\1///", self.ANYWHERE),
|
||||
# Strip trailing comments from preprocessor directives.
|
||||
(re.compile(r"(^#.*)//.*"), r"\1", self.ANYWHERE),
|
||||
# Convert remaining trailing comments to doxygen style, unless they are
|
||||
# documenting the end of a block.
|
||||
(re.compile(r"([^} ]\s+)//(?=[^/])"), r"\1///<", self.ANYWHERE),
|
||||
]
|
||||
|
||||
# Remove any comment lines that consist of only punctuation (banners).
|
||||
# We only allow a maximum of two spaces before the punctuation so we
|
||||
# don't accidentally get rid of code examples with bare braces and
|
||||
# whatnot.
|
||||
(re.compile(r'(^\s*)//\s{0,2}[-=#/]+$'), r'\1//\n', self.ANYWHERE),
|
||||
def Transform(self, line):
|
||||
"""Performs the regexp transformations defined by self.substitutions.
|
||||
|
||||
# If we find something that looks like a list item that is indented four
|
||||
# or more spaces, pull it back to the left so doxygen's Markdown engine
|
||||
# doesn't treat it like a code block.
|
||||
(re.compile(r'(^\s*)//\s{4,}([-\d*].*)'), r'\1 \2', self.COMMENT),
|
||||
Args:
|
||||
line: The line to transform.
|
||||
|
||||
# Replace TODO(user) in a comment with @todo (someone)
|
||||
(re.compile(r'TODO'), r'@todo ', self.COMMENT),
|
||||
|
||||
# Replace leading 'Note:' or 'Note that' in a comment with @note
|
||||
(re.compile(r'(\/\/\s+)Note(?:\:| that)', re.I), r'\1@note',
|
||||
self.COMMENT),
|
||||
|
||||
# Replace leading 'Warning:' in a comment with @warning
|
||||
(re.compile(r'(\/\/\s+)Warning:', re.I), r'\1@warning', self.COMMENT),
|
||||
|
||||
# Replace leading 'Deprecated' in a comment with @deprecated
|
||||
(re.compile(r'(\/\/\s+)Deprecated[^\w\s]*', re.I), r'\1@deprecated',
|
||||
self.COMMENT),
|
||||
|
||||
# Replace pipe-delimited parameter names with backtick-delimiters
|
||||
(re.compile(r'\|(\w+)\|'), r'`\1`', self.COMMENT),
|
||||
|
||||
# Convert standalone comment lines to Doxygen style.
|
||||
(re.compile(r'(^\s*)//(?=[^/])'), r'\1///', self.ANYWHERE),
|
||||
|
||||
# Strip trailing comments from preprocessor directives.
|
||||
(re.compile(r'(^#.*)//.*'), r'\1', self.ANYWHERE),
|
||||
|
||||
# Convert remaining trailing comments to doxygen style, unless they are
|
||||
# documenting the end of a block.
|
||||
(re.compile(r'([^} ]\s+)//(?=[^/])'), r'\1///<', self.ANYWHERE),
|
||||
]
|
||||
|
||||
def Transform(self, line):
|
||||
"""Performs the regexp transformations defined by self.substitutions.
|
||||
|
||||
Args:
|
||||
line: The line to transform.
|
||||
|
||||
Returns:
|
||||
The resulting line.
|
||||
"""
|
||||
for (regex, repl, where) in self.substitutions:
|
||||
if where is self.COMMENT and not self.comment_regex.match(line):
|
||||
Returns:
|
||||
The resulting line.
|
||||
"""
|
||||
for regex, repl, where in self.substitutions:
|
||||
if where is self.COMMENT and not self.comment_regex.match(line):
|
||||
return line
|
||||
line = regex.sub(repl, line)
|
||||
return line
|
||||
line = regex.sub(repl, line)
|
||||
return line
|
||||
|
||||
def AppendToBufferedLine(self, text):
|
||||
"""Appends text to the last buffered empty line.
|
||||
def AppendToBufferedLine(self, text):
|
||||
"""Appends text to the last buffered empty line.
|
||||
|
||||
Empty lines are buffered rather than being written out directly. This lets
|
||||
us retroactively rewrite buffered lines to include markup that affects the
|
||||
following line, while avoiding the line number offset that would result from
|
||||
inserting a line that wasn't in the original source.
|
||||
Empty lines are buffered rather than being written out directly. This lets
|
||||
us retroactively rewrite buffered lines to include markup that affects the
|
||||
following line, while avoiding the line number offset that would result from
|
||||
inserting a line that wasn't in the original source.
|
||||
|
||||
Args:
|
||||
text: The text to append to the line.
|
||||
Args:
|
||||
text: The text to append to the line.
|
||||
|
||||
Returns:
|
||||
True if there was an available empty line to which text could be
|
||||
appended, and False otherwise.
|
||||
"""
|
||||
if self.empty_line_buffer:
|
||||
last_line = self.empty_line_buffer.pop().rstrip()
|
||||
last_line += text + '\n'
|
||||
self.empty_line_buffer.append(last_line)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
Returns:
|
||||
True if there was an available empty line to which text could be
|
||||
appended, and False otherwise.
|
||||
"""
|
||||
if self.empty_line_buffer:
|
||||
last_line = self.empty_line_buffer.pop().rstrip()
|
||||
last_line += text + "\n"
|
||||
self.empty_line_buffer.append(last_line)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def ConvertCodeBlock(self, line):
|
||||
"""Converts any code block that may begin or end on this line.
|
||||
def ConvertCodeBlock(self, line):
|
||||
"""Converts any code block that may begin or end on this line.
|
||||
|
||||
Doxygen has (at least) two kinds of code blocks. Any block indented at
|
||||
least four spaces gets formatted as code, but (for some reason) no syntax
|
||||
highlighting is applied. Any block surrounded by "~~~" on both sides is
|
||||
also treated as code, but these are syntax highlighted intelligently
|
||||
depending on the file type. We typically write code blocks in the former
|
||||
style, but we'd like them to be highlighted, so this function converts them
|
||||
to the latter style by adding in the ~~~ lines.
|
||||
Doxygen has (at least) two kinds of code blocks. Any block indented at
|
||||
least four spaces gets formatted as code, but (for some reason) no syntax
|
||||
highlighting is applied. Any block surrounded by "~~~" on both sides is
|
||||
also treated as code, but these are syntax highlighted intelligently
|
||||
depending on the file type. We typically write code blocks in the former
|
||||
style, but we'd like them to be highlighted, so this function converts them
|
||||
to the latter style by adding in the ~~~ lines.
|
||||
|
||||
To make this a bit more complicated, we would really prefer not to insert
|
||||
new lines into the file, since that will make the line numbers shown in
|
||||
doxygen not match the line numbers in the actual source code. For this
|
||||
reason, we only perform the conversion if at least one "blank" line (empty
|
||||
comment line) appears before the start of the code block. If we get down to
|
||||
the bottom of the block and there's no blank line after it, we will be
|
||||
forced to add a line, since we can't go back and undo what we already did.
|
||||
To make this a bit more complicated, we would really prefer not to insert
|
||||
new lines into the file, since that will make the line numbers shown in
|
||||
doxygen not match the line numbers in the actual source code. For this
|
||||
reason, we only perform the conversion if at least one "blank" line (empty
|
||||
comment line) appears before the start of the code block. If we get down to
|
||||
the bottom of the block and there's no blank line after it, we will be
|
||||
forced to add a line, since we can't go back and undo what we already did.
|
||||
|
||||
Args:
|
||||
line: The line to process.
|
||||
Args:
|
||||
line: The line to process.
|
||||
|
||||
Returns:
|
||||
The converted line.
|
||||
"""
|
||||
if not self.in_code_block and re.match(r'\s*///\s{4,}', line):
|
||||
if self.AppendToBufferedLine(' ~~~'):
|
||||
# If this fails, we'll just leave it un-highlighted.
|
||||
self.in_code_block = True
|
||||
elif self.in_code_block and not re.match(r'\s*///\s{4,}', line):
|
||||
if not self.AppendToBufferedLine(' ~~~'):
|
||||
# This is bad. We don't have a buffered line to use to end the code
|
||||
# block, so we'll have to insert one. This will cause the line
|
||||
# numbers to stop matching the original source, unfortunately.
|
||||
line = '/// ~~~\n' + line
|
||||
self.in_code_block = False
|
||||
return line
|
||||
Returns:
|
||||
The converted line.
|
||||
"""
|
||||
if not self.in_code_block and re.match(r"\s*///\s{4,}", line):
|
||||
if self.AppendToBufferedLine(" ~~~"):
|
||||
# If this fails, we'll just leave it un-highlighted.
|
||||
self.in_code_block = True
|
||||
elif self.in_code_block and not re.match(r"\s*///\s{4,}", line):
|
||||
if not self.AppendToBufferedLine(" ~~~"):
|
||||
# This is bad. We don't have a buffered line to use to end the code
|
||||
# block, so we'll have to insert one. This will cause the line
|
||||
# numbers to stop matching the original source, unfortunately.
|
||||
line = "/// ~~~\n" + line
|
||||
self.in_code_block = False
|
||||
return line
|
||||
|
||||
def ProcessLine(self, line):
|
||||
"""Processes a line.
|
||||
def ProcessLine(self, line):
|
||||
"""Processes a line.
|
||||
|
||||
If the line is an empty line inside a comment, we buffer it for possible
|
||||
rewriting later on. Otherwise, we transform it using our regexps and
|
||||
write it (as well as any buffered blank lines) out to the output.
|
||||
If the line is an empty line inside a comment, we buffer it for possible
|
||||
rewriting later on. Otherwise, we transform it using our regexps and
|
||||
write it (as well as any buffered blank lines) out to the output.
|
||||
|
||||
Args:
|
||||
line: The line to process.
|
||||
"""
|
||||
line = self.Transform(line)
|
||||
Args:
|
||||
line: The line to process.
|
||||
"""
|
||||
line = self.Transform(line)
|
||||
|
||||
if line.strip() == '///':
|
||||
# We may repurpose this empty line later, so don't write it out yet.
|
||||
self.empty_line_buffer.append(line)
|
||||
else:
|
||||
line = self.ConvertCodeBlock(line)
|
||||
# Flush the line buffer and write this line as well.
|
||||
for buffered_line in self.empty_line_buffer:
|
||||
self.out.write(buffered_line)
|
||||
self.empty_line_buffer = []
|
||||
self.out.write(line)
|
||||
if line.strip() == "///":
|
||||
# We may repurpose this empty line later, so don't write it out yet.
|
||||
self.empty_line_buffer.append(line)
|
||||
else:
|
||||
line = self.ConvertCodeBlock(line)
|
||||
# Flush the line buffer and write this line as well.
|
||||
for buffered_line in self.empty_line_buffer:
|
||||
self.out.write(buffered_line)
|
||||
self.empty_line_buffer = []
|
||||
self.out.write(line)
|
||||
|
||||
|
||||
def main(argv):
|
||||
sourcefile = argv[1]
|
||||
with open(sourcefile, 'r') as infile:
|
||||
formatter = DoxygenFormatter(sys.stdout)
|
||||
for line in infile:
|
||||
formatter.ProcessLine(line)
|
||||
sourcefile = argv[1]
|
||||
with open(sourcefile, "r") as infile:
|
||||
formatter = DoxygenFormatter(sys.stdout)
|
||||
for line in infile:
|
||||
formatter.ProcessLine(line)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
|
||||
@@ -18,249 +18,234 @@ import re
|
||||
|
||||
|
||||
def main(version):
|
||||
"""For each doc section, edit the doxy and header files, and generate the doc."""
|
||||
sections = create_section_data()
|
||||
doxy_tmp = 'tools/doc/tmp.doxy'
|
||||
header_tmp = 'tools/doc/header.tmp.html'
|
||||
footer_tmp = 'tools/doc/footer.tmp.html'
|
||||
style_sheet_tmp = 'tools/doc/styleSheet.tmp.css'
|
||||
"""For each doc section, edit the doxy and header files, and generate the doc."""
|
||||
sections = create_section_data()
|
||||
doxy_tmp = "tools/doc/tmp.doxy"
|
||||
header_tmp = "tools/doc/header.tmp.html"
|
||||
footer_tmp = "tools/doc/footer.tmp.html"
|
||||
style_sheet_tmp = "tools/doc/styleSheet.tmp.css"
|
||||
|
||||
for section in sections:
|
||||
output_dir = section['output_dir']
|
||||
project_name = section['project name']
|
||||
title = section['title']
|
||||
doxyfile = 'tools/doc/' + section['doxyfile']
|
||||
headerfile = 'tools/doc/' + section['headerfile']
|
||||
footerfile = 'tools/doc/' + section['footerfile']
|
||||
stylesheetfile = 'tools/doc/' + section['styleSheetfile']
|
||||
input_files = section['input_files']
|
||||
# Edit doxyfile.
|
||||
project_name_string = 'PROJECT_NAME = ' + project_name
|
||||
project_number_string = 'PROJECT_NUMBER = ' + version
|
||||
html_output_string = 'HTML_OUTPUT = ' + output_dir
|
||||
input_string = 'INPUT = ' + input_files
|
||||
f = open(doxyfile, 'r')
|
||||
g = open(doxy_tmp, 'w')
|
||||
filedata = f.read()
|
||||
filedata = re.sub('PROJECT_NAME', project_name_string, filedata)
|
||||
filedata = re.sub('PROJECT_NUMBER', project_number_string, filedata)
|
||||
filedata = re.sub('HTML_OUTPUT', html_output_string, filedata)
|
||||
if input_files:
|
||||
filedata = re.sub(r'INPUT.*=.*', input_string, filedata)
|
||||
# Write filedata.
|
||||
g.write(filedata)
|
||||
f.close()
|
||||
g.close()
|
||||
for section in sections:
|
||||
output_dir = section["output_dir"]
|
||||
project_name = section["project name"]
|
||||
title = section["title"]
|
||||
doxyfile = "tools/doc/" + section["doxyfile"]
|
||||
headerfile = "tools/doc/" + section["headerfile"]
|
||||
footerfile = "tools/doc/" + section["footerfile"]
|
||||
stylesheetfile = "tools/doc/" + section["styleSheetfile"]
|
||||
input_files = section["input_files"]
|
||||
# Edit doxyfile.
|
||||
project_name_string = "PROJECT_NAME = " + project_name
|
||||
project_number_string = "PROJECT_NUMBER = " + version
|
||||
html_output_string = "HTML_OUTPUT = " + output_dir
|
||||
input_string = "INPUT = " + input_files
|
||||
f = open(doxyfile, "r")
|
||||
g = open(doxy_tmp, "w")
|
||||
filedata = f.read()
|
||||
filedata = re.sub("PROJECT_NAME", project_name_string, filedata)
|
||||
filedata = re.sub("PROJECT_NUMBER", project_number_string, filedata)
|
||||
filedata = re.sub("HTML_OUTPUT", html_output_string, filedata)
|
||||
if input_files:
|
||||
filedata = re.sub(r"INPUT.*=.*", input_string, filedata)
|
||||
# Write filedata.
|
||||
g.write(filedata)
|
||||
f.close()
|
||||
g.close()
|
||||
|
||||
# Edit header file.
|
||||
f = open(headerfile, 'r')
|
||||
g = open(header_tmp, 'w')
|
||||
filedata = f.read()
|
||||
filedata = re.sub('Banner Text', 'Google OR-Tools ' + version,
|
||||
filedata)
|
||||
filedata = re.sub('Page Title', title, filedata)
|
||||
# Write filedata.
|
||||
g.write(filedata)
|
||||
f.close()
|
||||
g.close()
|
||||
# Edit header file.
|
||||
f = open(headerfile, "r")
|
||||
g = open(header_tmp, "w")
|
||||
filedata = f.read()
|
||||
filedata = re.sub("Banner Text", "Google OR-Tools " + version, filedata)
|
||||
filedata = re.sub("Page Title", title, filedata)
|
||||
# Write filedata.
|
||||
g.write(filedata)
|
||||
f.close()
|
||||
g.close()
|
||||
|
||||
# Edit footer file.
|
||||
f = open(footerfile, 'r')
|
||||
g = open(footer_tmp, 'w')
|
||||
filedata = f.read()
|
||||
# Write filedata.
|
||||
g.write(filedata)
|
||||
f.close()
|
||||
g.close()
|
||||
# Edit footer file.
|
||||
f = open(footerfile, "r")
|
||||
g = open(footer_tmp, "w")
|
||||
filedata = f.read()
|
||||
# Write filedata.
|
||||
g.write(filedata)
|
||||
f.close()
|
||||
g.close()
|
||||
|
||||
# Edit style sheet file.
|
||||
f = open(stylesheetfile, 'r')
|
||||
g = open(style_sheet_tmp, 'w')
|
||||
filedata = f.read()
|
||||
# Write filedata.
|
||||
g.write(filedata)
|
||||
f.close()
|
||||
g.close()
|
||||
# Edit style sheet file.
|
||||
f = open(stylesheetfile, "r")
|
||||
g = open(style_sheet_tmp, "w")
|
||||
filedata = f.read()
|
||||
# Write filedata.
|
||||
g.write(filedata)
|
||||
f.close()
|
||||
g.close()
|
||||
|
||||
# Clean previous doc.
|
||||
os.system('rm -rf docs/' + output_dir)
|
||||
# Generate the doc.
|
||||
os.system(f'doxygen {doxy_tmp}')
|
||||
# Remove temp files.
|
||||
os.system(f'rm {doxy_tmp}')
|
||||
os.system(f'rm {header_tmp}')
|
||||
os.system(f'rm {footer_tmp}')
|
||||
os.system(f'rm {style_sheet_tmp}')
|
||||
# Clean previous doc.
|
||||
os.system("rm -rf docs/" + output_dir)
|
||||
# Generate the doc.
|
||||
os.system(f"doxygen {doxy_tmp}")
|
||||
# Remove temp files.
|
||||
os.system(f"rm {doxy_tmp}")
|
||||
os.system(f"rm {header_tmp}")
|
||||
os.system(f"rm {footer_tmp}")
|
||||
os.system(f"rm {style_sheet_tmp}")
|
||||
|
||||
|
||||
def create_section_data():
|
||||
"""Generate each section configuration."""
|
||||
sections = [{
|
||||
'output_dir':
|
||||
'cpp_algorithms',
|
||||
'project name':
|
||||
'Algorithms',
|
||||
'title':
|
||||
'C++ Reference: Algorithms',
|
||||
'doxyfile':
|
||||
'cpp.doxy.in',
|
||||
'headerfile':
|
||||
'cpp.header.html.in',
|
||||
'footerfile':
|
||||
'all.footer.html.in',
|
||||
'styleSheetfile':
|
||||
'all.styleSheet.css.in',
|
||||
'input_files':
|
||||
'ortools/algorithms/dense_doubly_linked_list.h ' +
|
||||
'ortools/algorithms/dynamic_partition.h ' +
|
||||
'ortools/algorithms/dynamic_permutation.h ' +
|
||||
'ortools/algorithms/find_graph_symmetries.h ' +
|
||||
'ortools/algorithms/hungarian.h ' +
|
||||
'ortools/algorithms/knapsack_solver.h ' +
|
||||
'ortools/algorithms/sparse_permutation.h'
|
||||
}, {
|
||||
'output_dir':
|
||||
'cpp_sat',
|
||||
'project name':
|
||||
'CP-SAT',
|
||||
'title':
|
||||
'C++ Reference: CP-SAT',
|
||||
'doxyfile':
|
||||
'cpp.doxy.in',
|
||||
'headerfile':
|
||||
'cpp.header.html.in',
|
||||
'footerfile':
|
||||
'all.footer.html.in',
|
||||
'styleSheetfile':
|
||||
'all.styleSheet.css.in',
|
||||
'input_files':
|
||||
'ortools/sat/cp_model.h ' + 'ortools/sat/cp_model_solver.h ' +
|
||||
'ortools/sat/model.h ' + 'ortools/util/sorted_interval_list.h ' +
|
||||
'ortools/util/time_limit.h ' +
|
||||
'ortools/gen/ortools/sat/boolean_problem.pb.h ' +
|
||||
'ortools/gen/ortools/sat/cp_model.pb.h ' +
|
||||
'ortools/gen/ortools/sat/sat_parameters.pb.h'
|
||||
}, {
|
||||
'output_dir':
|
||||
'cpp_graph',
|
||||
'project name':
|
||||
'Graph',
|
||||
'title':
|
||||
'C++ Reference: Graph',
|
||||
'doxyfile':
|
||||
'cpp.doxy.in',
|
||||
'headerfile':
|
||||
'cpp.header.html.in',
|
||||
'footerfile':
|
||||
'all.footer.html.in',
|
||||
'styleSheetfile':
|
||||
'all.styleSheet.css.in',
|
||||
'input_files':
|
||||
'ortools/graph/christofides.h ' + 'ortools/graph/cliques.h ' +
|
||||
'ortools/graph/connected_components.h ' +
|
||||
'ortools/graph/connectivity.h ' +
|
||||
'ortools/graph/eulerian_path.h ' + 'ortools/graph/graph.h ' +
|
||||
'ortools/graph/graphs.h ' + 'ortools/graph/hamiltonian_path.h ' +
|
||||
'ortools/graph/graph_io.h ' + 'ortools/graph/iterators.h ' +
|
||||
'ortools/graph/linear_assignment.h ' + 'ortools/graph/max_flow.h ' +
|
||||
'ortools/graph/min_cost_flow.h ' +
|
||||
'ortools/graph/minimum_spanning_tree.h ' +
|
||||
'ortools/graph/one_tree_lower_bound.h ' +
|
||||
'ortools/graph/shortestpaths.h ' +
|
||||
'ortools/graph/strongly_connected_components.h ' +
|
||||
'ortools/graph/util.h ' +
|
||||
'ortools/gen/ortools/graph/flow_problem.pb.h '
|
||||
}, {
|
||||
'output_dir':
|
||||
'cpp_linear',
|
||||
'project name':
|
||||
'Linear solver',
|
||||
'title':
|
||||
'C++ Reference: Linear solver',
|
||||
'doxyfile':
|
||||
'cpp.doxy.in',
|
||||
'headerfile':
|
||||
'cpp.header.html.in',
|
||||
'footerfile':
|
||||
'all.footer.html.in',
|
||||
'styleSheetfile':
|
||||
'all.styleSheet.css.in',
|
||||
'input_files':
|
||||
'ortools/linear_solver/linear_expr.h ' +
|
||||
'ortools/linear_solver/linear_solver.h ' +
|
||||
'ortools/linear_solver/model_exporter.h ' +
|
||||
'ortools/linear_solver/model_exporter_swig_helper.h ' +
|
||||
'ortools/linear_solver/model_validator.h ' +
|
||||
'ortools/gen/ortools/linear_solver/linear_solver.pb.h '
|
||||
}, {
|
||||
'output_dir':
|
||||
'cpp_routing',
|
||||
'project name':
|
||||
'Routing',
|
||||
'title':
|
||||
'C++ Reference: Routing',
|
||||
'doxyfile':
|
||||
'cpp.doxy.in',
|
||||
'headerfile':
|
||||
'cpp.header.html.in',
|
||||
'footerfile':
|
||||
'all.footer.html.in',
|
||||
'styleSheetfile':
|
||||
'all.styleSheet.css.in',
|
||||
'input_files':
|
||||
'ortools/constraint_solver/constraint_solver.h ' +
|
||||
'ortools/constraint_solver/constraint_solveri.h ' +
|
||||
'ortools/constraint_solver/routing.h ' +
|
||||
'ortools/constraint_solver/routing_index_manager.h ' +
|
||||
'ortools/constraint_solver/routing_lp_scheduling.h ' +
|
||||
'ortools/constraint_solver/routing_neighborhoods.h ' +
|
||||
'ortools/constraint_solver/routing_parameters.h ' +
|
||||
'ortools/constraint_solver/routing_types.h ' +
|
||||
'ortools/gen/ortools/constraint_solver/assignment.pb.h ' +
|
||||
'ortools/gen/ortools/constraint_solver/demon_profiler.pb.h ' +
|
||||
'ortools/gen/ortools/constraint_solver/routing_enums.pb.h ' +
|
||||
'ortools/gen/ortools/constraint_solver/routing_parameters.pb.h ' +
|
||||
'ortools/gen/ortools/constraint_solver/search_limit.pb.h ' +
|
||||
'ortools/gen/ortools/constraint_solver/solver_parameters.pb.h '
|
||||
}, {
|
||||
'output_dir': 'cpp',
|
||||
'project name': 'OR-Tools',
|
||||
'title': 'C++ Reference',
|
||||
'doxyfile': 'cpp.doxy.in',
|
||||
'headerfile': 'default.header.html.in',
|
||||
'footerfile': 'default.footer.html.in',
|
||||
'styleSheetfile': 'default.styleSheet.css.in',
|
||||
'input_files': 'ortools ' + 'tools/doc'
|
||||
}, {
|
||||
'output_dir': 'dotnet',
|
||||
'project name': 'OR-Tools',
|
||||
'title': '.Net Reference',
|
||||
'doxyfile': 'dotnet.doxy.in',
|
||||
'headerfile': 'dotnet.header.html.in',
|
||||
'footerfile': 'all.footer.html.in',
|
||||
'styleSheetfile': 'all.styleSheet.css.in',
|
||||
'input_files': 'ortools ' + 'tools/doc'
|
||||
}, {
|
||||
'output_dir': 'java',
|
||||
'project name': 'OR-Tools',
|
||||
'title': 'Java Reference',
|
||||
'doxyfile': 'java.doxy.in',
|
||||
'headerfile': 'java.header.html.in',
|
||||
'footerfile': 'all.footer.html.in',
|
||||
'styleSheetfile': 'all.styleSheet.css.in',
|
||||
'input_files': 'ortools ' + 'tools/doc'
|
||||
}]
|
||||
return sections
|
||||
"""Generate each section configuration."""
|
||||
sections = [
|
||||
{
|
||||
"output_dir": "cpp_algorithms",
|
||||
"project name": "Algorithms",
|
||||
"title": "C++ Reference: Algorithms",
|
||||
"doxyfile": "cpp.doxy.in",
|
||||
"headerfile": "cpp.header.html.in",
|
||||
"footerfile": "all.footer.html.in",
|
||||
"styleSheetfile": "all.styleSheet.css.in",
|
||||
"input_files": (
|
||||
"ortools/algorithms/dense_doubly_linked_list.h "
|
||||
+ "ortools/algorithms/dynamic_partition.h "
|
||||
+ "ortools/algorithms/dynamic_permutation.h "
|
||||
+ "ortools/algorithms/find_graph_symmetries.h "
|
||||
+ "ortools/algorithms/hungarian.h "
|
||||
+ "ortools/algorithms/knapsack_solver.h "
|
||||
+ "ortools/algorithms/sparse_permutation.h"
|
||||
),
|
||||
},
|
||||
{
|
||||
"output_dir": "cpp_sat",
|
||||
"project name": "CP-SAT",
|
||||
"title": "C++ Reference: CP-SAT",
|
||||
"doxyfile": "cpp.doxy.in",
|
||||
"headerfile": "cpp.header.html.in",
|
||||
"footerfile": "all.footer.html.in",
|
||||
"styleSheetfile": "all.styleSheet.css.in",
|
||||
"input_files": (
|
||||
"ortools/sat/cp_model.h "
|
||||
+ "ortools/sat/cp_model_solver.h "
|
||||
+ "ortools/sat/model.h "
|
||||
+ "ortools/util/sorted_interval_list.h "
|
||||
+ "ortools/util/time_limit.h "
|
||||
+ "ortools/gen/ortools/sat/boolean_problem.pb.h "
|
||||
+ "ortools/gen/ortools/sat/cp_model.pb.h "
|
||||
+ "ortools/gen/ortools/sat/sat_parameters.pb.h"
|
||||
),
|
||||
},
|
||||
{
|
||||
"output_dir": "cpp_graph",
|
||||
"project name": "Graph",
|
||||
"title": "C++ Reference: Graph",
|
||||
"doxyfile": "cpp.doxy.in",
|
||||
"headerfile": "cpp.header.html.in",
|
||||
"footerfile": "all.footer.html.in",
|
||||
"styleSheetfile": "all.styleSheet.css.in",
|
||||
"input_files": (
|
||||
"ortools/graph/christofides.h "
|
||||
+ "ortools/graph/cliques.h "
|
||||
+ "ortools/graph/connected_components.h "
|
||||
+ "ortools/graph/connectivity.h "
|
||||
+ "ortools/graph/eulerian_path.h "
|
||||
+ "ortools/graph/graph.h "
|
||||
+ "ortools/graph/graphs.h "
|
||||
+ "ortools/graph/hamiltonian_path.h "
|
||||
+ "ortools/graph/graph_io.h "
|
||||
+ "ortools/graph/iterators.h "
|
||||
+ "ortools/graph/linear_assignment.h "
|
||||
+ "ortools/graph/max_flow.h "
|
||||
+ "ortools/graph/min_cost_flow.h "
|
||||
+ "ortools/graph/minimum_spanning_tree.h "
|
||||
+ "ortools/graph/one_tree_lower_bound.h "
|
||||
+ "ortools/graph/shortestpaths.h "
|
||||
+ "ortools/graph/strongly_connected_components.h "
|
||||
+ "ortools/graph/util.h "
|
||||
+ "ortools/gen/ortools/graph/flow_problem.pb.h "
|
||||
),
|
||||
},
|
||||
{
|
||||
"output_dir": "cpp_linear",
|
||||
"project name": "Linear solver",
|
||||
"title": "C++ Reference: Linear solver",
|
||||
"doxyfile": "cpp.doxy.in",
|
||||
"headerfile": "cpp.header.html.in",
|
||||
"footerfile": "all.footer.html.in",
|
||||
"styleSheetfile": "all.styleSheet.css.in",
|
||||
"input_files": (
|
||||
"ortools/linear_solver/linear_expr.h "
|
||||
+ "ortools/linear_solver/linear_solver.h "
|
||||
+ "ortools/linear_solver/model_exporter.h "
|
||||
+ "ortools/linear_solver/model_exporter_swig_helper.h "
|
||||
+ "ortools/linear_solver/model_validator.h "
|
||||
+ "ortools/gen/ortools/linear_solver/linear_solver.pb.h "
|
||||
),
|
||||
},
|
||||
{
|
||||
"output_dir": "cpp_routing",
|
||||
"project name": "Routing",
|
||||
"title": "C++ Reference: Routing",
|
||||
"doxyfile": "cpp.doxy.in",
|
||||
"headerfile": "cpp.header.html.in",
|
||||
"footerfile": "all.footer.html.in",
|
||||
"styleSheetfile": "all.styleSheet.css.in",
|
||||
"input_files": (
|
||||
"ortools/constraint_solver/constraint_solver.h "
|
||||
+ "ortools/constraint_solver/constraint_solveri.h "
|
||||
+ "ortools/constraint_solver/routing.h "
|
||||
+ "ortools/constraint_solver/routing_index_manager.h "
|
||||
+ "ortools/constraint_solver/routing_lp_scheduling.h "
|
||||
+ "ortools/constraint_solver/routing_neighborhoods.h "
|
||||
+ "ortools/constraint_solver/routing_parameters.h "
|
||||
+ "ortools/constraint_solver/routing_types.h "
|
||||
+ "ortools/gen/ortools/constraint_solver/assignment.pb.h "
|
||||
+ "ortools/gen/ortools/constraint_solver/demon_profiler.pb.h "
|
||||
+ "ortools/gen/ortools/constraint_solver/routing_enums.pb.h "
|
||||
+ "ortools/gen/ortools/constraint_solver/routing_parameters.pb.h "
|
||||
+ "ortools/gen/ortools/constraint_solver/search_limit.pb.h "
|
||||
+ "ortools/gen/ortools/constraint_solver/solver_parameters.pb.h "
|
||||
),
|
||||
},
|
||||
{
|
||||
"output_dir": "cpp",
|
||||
"project name": "OR-Tools",
|
||||
"title": "C++ Reference",
|
||||
"doxyfile": "cpp.doxy.in",
|
||||
"headerfile": "default.header.html.in",
|
||||
"footerfile": "default.footer.html.in",
|
||||
"styleSheetfile": "default.styleSheet.css.in",
|
||||
"input_files": "ortools " + "tools/doc",
|
||||
},
|
||||
{
|
||||
"output_dir": "dotnet",
|
||||
"project name": "OR-Tools",
|
||||
"title": ".Net Reference",
|
||||
"doxyfile": "dotnet.doxy.in",
|
||||
"headerfile": "dotnet.header.html.in",
|
||||
"footerfile": "all.footer.html.in",
|
||||
"styleSheetfile": "all.styleSheet.css.in",
|
||||
"input_files": "ortools " + "tools/doc",
|
||||
},
|
||||
{
|
||||
"output_dir": "java",
|
||||
"project name": "OR-Tools",
|
||||
"title": "Java Reference",
|
||||
"doxyfile": "java.doxy.in",
|
||||
"headerfile": "java.header.html.in",
|
||||
"footerfile": "all.footer.html.in",
|
||||
"styleSheetfile": "all.styleSheet.css.in",
|
||||
"input_files": "ortools " + "tools/doc",
|
||||
},
|
||||
]
|
||||
return sections
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
version_file = open('Version.txt', 'r')
|
||||
version_file_data = version_file.read()
|
||||
version_file.close()
|
||||
major_pattern = re.compile(r'OR_TOOLS_MAJOR=(\d)')
|
||||
minor_pattern = re.compile(r'OR_TOOLS_MINOR=(\d)')
|
||||
major = major_pattern.findall(version_file_data)[0]
|
||||
minor = minor_pattern.findall(version_file_data)[0]
|
||||
if __name__ == "__main__":
|
||||
version_file = open("Version.txt", "r")
|
||||
version_file_data = version_file.read()
|
||||
version_file.close()
|
||||
major_pattern = re.compile(r"OR_TOOLS_MAJOR=(\d)")
|
||||
minor_pattern = re.compile(r"OR_TOOLS_MINOR=(\d)")
|
||||
major = major_pattern.findall(version_file_data)[0]
|
||||
minor = minor_pattern.findall(version_file_data)[0]
|
||||
|
||||
version_number = f'{major}.{minor}'
|
||||
main(version_number)
|
||||
version_number = f"{major}.{minor}"
|
||||
main(version_number)
|
||||
|
||||
Reference in New Issue
Block a user