"""
Integer factorization
"""
from __future__ import print_function, division
import random
import math
from .primetest import isprime
from .generate import sieve, primerange, nextprime
from sympy.core import sympify
from sympy.core.evalf import bitcount
from sympy.core.logic import fuzzy_and
from sympy.core.numbers import igcd, Rational
from sympy.core.power import integer_nthroot, Pow
from sympy.core.mul import Mul
from sympy.core.compatibility import as_int, SYMPY_INTS, range
from sympy.core.singleton import S
from sympy.core.function import Function
small_trailing = [i and max(int(not i % 2**j) and j for j in range(1, 8))
for i in range(256)]
[docs]def smoothness(n):
"""
Return the B-smooth and B-power smooth values of n.
The smoothness of n is the largest prime factor of n; the power-
smoothness is the largest divisor raised to its multiplicity.
>>> from sympy.ntheory.factor_ import smoothness
>>> smoothness(2**7*3**2)
(3, 128)
>>> smoothness(2**4*13)
(13, 16)
>>> smoothness(2)
(2, 2)
See Also
========
factorint, smoothness_p
"""
if n == 1:
return (1, 1) # not prime, but otherwise this causes headaches
facs = factorint(n)
return max(facs), max(m**facs[m] for m in facs)
[docs]def smoothness_p(n, m=-1, power=0, visual=None):
"""
Return a list of [m, (p, (M, sm(p + m), psm(p + m)))...]
where:
1. p**M is the base-p divisor of n
2. sm(p + m) is the smoothness of p + m (m = -1 by default)
3. psm(p + m) is the power smoothness of p + m
The list is sorted according to smoothness (default) or by power smoothness
if power=1.
The smoothness of the numbers to the left (m = -1) or right (m = 1) of a
factor govern the results that are obtained from the p +/- 1 type factoring
methods.
>>> from sympy.ntheory.factor_ import smoothness_p, factorint
>>> smoothness_p(10431, m=1)
(1, [(3, (2, 2, 4)), (19, (1, 5, 5)), (61, (1, 31, 31))])
>>> smoothness_p(10431)
(-1, [(3, (2, 2, 2)), (19, (1, 3, 9)), (61, (1, 5, 5))])
>>> smoothness_p(10431, power=1)
(-1, [(3, (2, 2, 2)), (61, (1, 5, 5)), (19, (1, 3, 9))])
If visual=True then an annotated string will be returned:
>>> print(smoothness_p(21477639576571, visual=1))
p**i=4410317**1 has p-1 B=1787, B-pow=1787
p**i=4869863**1 has p-1 B=2434931, B-pow=2434931
This string can also be generated directly from a factorization dictionary
and vice versa:
>>> factorint(17*9)
{3: 2, 17: 1}
>>> smoothness_p(_)
'p**i=3**2 has p-1 B=2, B-pow=2\\np**i=17**1 has p-1 B=2, B-pow=16'
>>> smoothness_p(_)
{3: 2, 17: 1}
The table of the output logic is:
====== ====== ======= =======
| Visual
------ ----------------------
Input True False other
====== ====== ======= =======
dict str tuple str
str str tuple dict
tuple str tuple str
n str tuple tuple
mul str tuple tuple
====== ====== ======= =======
See Also
========
factorint, smoothness
"""
from sympy.utilities import flatten
# visual must be True, False or other (stored as None)
if visual in (1, 0):
visual = bool(visual)
elif visual not in (True, False):
visual = None
if type(n) is str:
if visual:
return n
d = {}
for li in n.splitlines():
k, v = [int(i) for i in
li.split('has')[0].split('=')[1].split('**')]
d[k] = v
if visual is not True and visual is not False:
return d
return smoothness_p(d, visual=False)
elif type(n) is not tuple:
facs = factorint(n, visual=False)
if power:
k = -1
else:
k = 1
if type(n) is not tuple:
rv = (m, sorted([(f,
tuple([M] + list(smoothness(f + m))))
for f, M in [i for i in facs.items()]],
key=lambda x: (x[1][k], x[0])))
else:
rv = n
if visual is False or (visual is not True) and (type(n) in [int, Mul]):
return rv
lines = []
for dat in rv[1]:
dat = flatten(dat)
dat.insert(2, m)
lines.append('p**i=%i**%i has p%+i B=%i, B-pow=%i' % tuple(dat))
return '\n'.join(lines)
[docs]def trailing(n):
"""Count the number of trailing zero digits in the binary
representation of n, i.e. determine the largest power of 2
that divides n.
Examples
========
>>> from sympy import trailing
>>> trailing(128)
7
>>> trailing(63)
0
"""
n = int(n)
if not n:
return 0
low_byte = n & 0xff
if low_byte:
return small_trailing[low_byte]
# 2**m is quick for z up through 2**30
z = bitcount(n) - 1
if isinstance(z, SYMPY_INTS):
if n == 1 << z:
return z
t = 0
p = 8
while not n & 1:
while not n & ((1 << p) - 1):
n >>= p
t += p
p *= 2
p //= 2
return t
[docs]def multiplicity(p, n):
"""
Find the greatest integer m such that p**m divides n.
Examples
========
>>> from sympy.ntheory import multiplicity
>>> from sympy.core.numbers import Rational as R
>>> [multiplicity(5, n) for n in [8, 5, 25, 125, 250]]
[0, 1, 2, 3, 3]
>>> multiplicity(3, R(1, 9))
-2
"""
try:
p, n = as_int(p), as_int(n)
except ValueError:
if all(isinstance(i, (SYMPY_INTS, Rational)) for i in (p, n)):
try:
p = Rational(p)
n = Rational(n)
if p.q == 1:
if n.p == 1:
return -multiplicity(p.p, n.q)
return S.Zero
elif p.p == 1:
return multiplicity(p.q, n.q)
else:
like = min(
multiplicity(p.p, n.p),
multiplicity(p.q, n.q))
cross = min(
multiplicity(p.q, n.p),
multiplicity(p.p, n.q))
return like - cross
except AttributeError:
pass
raise ValueError('expecting ints or fractions, got %s and %s' % (p, n))
if n == 0:
raise ValueError('no such integer exists: multiplicity of %s is not-defined' %(n))
if p == 2:
return trailing(n)
if p < 2:
raise ValueError('p must be an integer, 2 or larger, but got %s' % p)
if p == n:
return 1
m = 0
n, rem = divmod(n, p)
while not rem:
m += 1
if m > 5:
# The multiplicity could be very large. Better
# to increment in powers of two
e = 2
while 1:
ppow = p**e
if ppow < n:
nnew, rem = divmod(n, ppow)
if not rem:
m += e
e *= 2
n = nnew
continue
return m + multiplicity(p, n)
n, rem = divmod(n, p)
return m
[docs]def perfect_power(n, candidates=None, big=True, factor=True):
"""
Return ``(b, e)`` such that ``n`` == ``b**e`` if ``n`` is a
perfect power; otherwise return ``False``.
By default, the base is recursively decomposed and the exponents
collected so the largest possible ``e`` is sought. If ``big=False``
then the smallest possible ``e`` (thus prime) will be chosen.
If ``candidates`` for exponents are given, they are assumed to be sorted
and the first one that is larger than the computed maximum will signal
failure for the routine.
If ``factor=True`` then simultaneous factorization of n is attempted
since finding a factor indicates the only possible root for n. This
is True by default since only a few small factors will be tested in
the course of searching for the perfect power.
Examples
========
>>> from sympy import perfect_power
>>> perfect_power(16)
(2, 4)
>>> perfect_power(16, big = False)
(4, 2)
"""
n = int(n)
if n < 3:
return False
logn = math.log(n, 2)
max_possible = int(logn) + 2 # only check values less than this
not_square = n % 10 in [2, 3, 7, 8] # squares cannot end in 2, 3, 7, 8
if not candidates:
candidates = primerange(2 + not_square, max_possible)
afactor = 2 + n % 2
for e in candidates:
if e < 3:
if e == 1 or e == 2 and not_square:
continue
if e > max_possible:
return False
# see if there is a factor present
if factor:
if n % afactor == 0:
# find what the potential power is
if afactor == 2:
e = trailing(n)
else:
e = multiplicity(afactor, n)
# if it's a trivial power we are done
if e == 1:
return False
# maybe the bth root of n is exact
r, exact = integer_nthroot(n, e)
if not exact:
# then remove this factor and check to see if
# any of e's factors are a common exponent; if
# not then it's not a perfect power
n //= afactor**e
m = perfect_power(n, candidates=primefactors(e), big=big)
if m is False:
return False
else:
r, m = m
# adjust the two exponents so the bases can
# be combined
g = igcd(m, e)
if g == 1:
return False
m //= g
e //= g
r, e = r**m*afactor**e, g
if not big:
e0 = primefactors(e)
if len(e0) > 1 or e0[0] != e:
e0 = e0[0]
r, e = r**(e//e0), e0
return r, e
else:
# get the next factor ready for the next pass through the loop
afactor = nextprime(afactor)
# Weed out downright impossible candidates
if logn/e < 40:
b = 2.0**(logn/e)
if abs(int(b + 0.5) - b) > 0.01:
continue
# now see if the plausible e makes a perfect power
r, exact = integer_nthroot(n, e)
if exact:
if big:
m = perfect_power(r, big=big, factor=factor)
if m is not False:
r, e = m[0], e*m[1]
return int(r), e
else:
return False
[docs]def pollard_rho(n, s=2, a=1, retries=5, seed=1234, max_steps=None, F=None):
r"""
Use Pollard's rho method to try to extract a nontrivial factor
of ``n``. The returned factor may be a composite number. If no
factor is found, ``None`` is returned.
The algorithm generates pseudo-random values of x with a generator
function, replacing x with F(x). If F is not supplied then the
function x**2 + ``a`` is used. The first value supplied to F(x) is ``s``.
Upon failure (if ``retries`` is > 0) a new ``a`` and ``s`` will be
supplied; the ``a`` will be ignored if F was supplied.
The sequence of numbers generated by such functions generally have a
a lead-up to some number and then loop around back to that number and
begin to repeat the sequence, e.g. 1, 2, 3, 4, 5, 3, 4, 5 -- this leader
and loop look a bit like the Greek letter rho, and thus the name, 'rho'.
For a given function, very different leader-loop values can be obtained
so it is a good idea to allow for retries:
>>> from sympy.ntheory.generate import cycle_length
>>> n = 16843009
>>> F = lambda x:(2048*pow(x, 2, n) + 32767) % n
>>> for s in range(5):
... print('loop length = %4i; leader length = %3i' % next(cycle_length(F, s)))
...
loop length = 2489; leader length = 42
loop length = 78; leader length = 120
loop length = 1482; leader length = 99
loop length = 1482; leader length = 285
loop length = 1482; leader length = 100
Here is an explicit example where there is a two element leadup to
a sequence of 3 numbers (11, 14, 4) that then repeat:
>>> x=2
>>> for i in range(9):
... x=(x**2+12)%17
... print(x)
...
16
13
11
14
4
11
14
4
11
>>> next(cycle_length(lambda x: (x**2+12)%17, 2))
(3, 2)
>>> list(cycle_length(lambda x: (x**2+12)%17, 2, values=True))
[16, 13, 11, 14, 4]
Instead of checking the differences of all generated values for a gcd
with n, only the kth and 2*kth numbers are checked, e.g. 1st and 2nd,
2nd and 4th, 3rd and 6th until it has been detected that the loop has been
traversed. Loops may be many thousands of steps long before rho finds a
factor or reports failure. If ``max_steps`` is specified, the iteration
is cancelled with a failure after the specified number of steps.
Examples
========
>>> from sympy import pollard_rho
>>> n=16843009
>>> F=lambda x:(2048*pow(x,2,n) + 32767) % n
>>> pollard_rho(n, F=F)
257
Use the default setting with a bad value of ``a`` and no retries:
>>> pollard_rho(n, a=n-2, retries=0)
If retries is > 0 then perhaps the problem will correct itself when
new values are generated for a:
>>> pollard_rho(n, a=n-2, retries=1)
257
References
==========
- Richard Crandall & Carl Pomerance (2005), "Prime Numbers:
A Computational Perspective", Springer, 2nd edition, 229-231
"""
n = int(n)
if n < 5:
raise ValueError('pollard_rho should receive n > 4')
prng = random.Random(seed + retries)
V = s
for i in range(retries + 1):
U = V
if not F:
F = lambda x: (pow(x, 2, n) + a) % n
j = 0
while 1:
if max_steps and (j > max_steps):
break
j += 1
U = F(U)
V = F(F(V)) # V is 2x further along than U
g = igcd(U - V, n)
if g == 1:
continue
if g == n:
break
return int(g)
V = prng.randint(0, n - 1)
a = prng.randint(1, n - 3) # for x**2 + a, a%n should not be 0 or -2
F = None
return None
[docs]def pollard_pm1(n, B=10, a=2, retries=0, seed=1234):
"""
Use Pollard's p-1 method to try to extract a nontrivial factor
of ``n``. Either a divisor (perhaps composite) or ``None`` is returned.
The value of ``a`` is the base that is used in the test gcd(a**M - 1, n).
The default is 2. If ``retries`` > 0 then if no factor is found after the
first attempt, a new ``a`` will be generated randomly (using the ``seed``)
and the process repeated.
Note: the value of M is lcm(1..B) = reduce(ilcm, range(2, B + 1)).
A search is made for factors next to even numbers having a power smoothness
less than ``B``. Choosing a larger B increases the likelihood of finding a
larger factor but takes longer. Whether a factor of n is found or not
depends on ``a`` and the power smoothness of the even mumber just less than
the factor p (hence the name p - 1).
Although some discussion of what constitutes a good ``a`` some
descriptions are hard to interpret. At the modular.math site referenced
below it is stated that if gcd(a**M - 1, n) = N then a**M % q**r is 1
for every prime power divisor of N. But consider the following:
>>> from sympy.ntheory.factor_ import smoothness_p, pollard_pm1
>>> n=257*1009
>>> smoothness_p(n)
(-1, [(257, (1, 2, 256)), (1009, (1, 7, 16))])
So we should (and can) find a root with B=16:
>>> pollard_pm1(n, B=16, a=3)
1009
If we attempt to increase B to 256 we find that it doesn't work:
>>> pollard_pm1(n, B=256)
>>>
But if the value of ``a`` is changed we find that only multiples of
257 work, e.g.:
>>> pollard_pm1(n, B=256, a=257)
1009
Checking different ``a`` values shows that all the ones that didn't
work had a gcd value not equal to ``n`` but equal to one of the
factors:
>>> from sympy.core.numbers import ilcm, igcd
>>> from sympy import factorint, Pow
>>> M = 1
>>> for i in range(2, 256):
... M = ilcm(M, i)
...
>>> set([igcd(pow(a, M, n) - 1, n) for a in range(2, 256) if
... igcd(pow(a, M, n) - 1, n) != n])
set([1009])
But does aM % d for every divisor of n give 1?
>>> aM = pow(255, M, n)
>>> [(d, aM%Pow(*d.args)) for d in factorint(n, visual=True).args]
[(257**1, 1), (1009**1, 1)]
No, only one of them. So perhaps the principle is that a root will
be found for a given value of B provided that:
1) the power smoothness of the p - 1 value next to the root
does not exceed B
2) a**M % p != 1 for any of the divisors of n.
By trying more than one ``a`` it is possible that one of them
will yield a factor.
Examples
========
With the default smoothness bound, this number can't be cracked:
>>> from sympy.ntheory import pollard_pm1, primefactors
>>> pollard_pm1(21477639576571)
Increasing the smoothness bound helps:
>>> pollard_pm1(21477639576571, B=2000)
4410317
Looking at the smoothness of the factors of this number we find:
>>> from sympy.utilities import flatten
>>> from sympy.ntheory.factor_ import smoothness_p, factorint
>>> print(smoothness_p(21477639576571, visual=1))
p**i=4410317**1 has p-1 B=1787, B-pow=1787
p**i=4869863**1 has p-1 B=2434931, B-pow=2434931
The B and B-pow are the same for the p - 1 factorizations of the divisors
because those factorizations had a very large prime factor:
>>> factorint(4410317 - 1)
{2: 2, 617: 1, 1787: 1}
>>> factorint(4869863-1)
{2: 1, 2434931: 1}
Note that until B reaches the B-pow value of 1787, the number is not cracked;
>>> pollard_pm1(21477639576571, B=1786)
>>> pollard_pm1(21477639576571, B=1787)
4410317
The B value has to do with the factors of the number next to the divisor,
not the divisors themselves. A worst case scenario is that the number next
to the factor p has a large prime divisisor or is a perfect power. If these
conditions apply then the power-smoothness will be about p/2 or p. The more
realistic is that there will be a large prime factor next to p requiring
a B value on the order of p/2. Although primes may have been searched for
up to this level, the p/2 is a factor of p - 1, something that we don't
know. The modular.math reference below states that 15% of numbers in the
range of 10**15 to 15**15 + 10**4 are 10**6 power smooth so a B of 10**6
will fail 85% of the time in that range. From 10**8 to 10**8 + 10**3 the
percentages are nearly reversed...but in that range the simple trial
division is quite fast.
References
==========
- Richard Crandall & Carl Pomerance (2005), "Prime Numbers:
A Computational Perspective", Springer, 2nd edition, 236-238
- http://modular.math.washington.edu/edu/2007/spring/ent/ent-html/node81.html
- http://www.cs.toronto.edu/~yuvalf/Factorization.pdf
"""
n = int(n)
if n < 4 or B < 3:
raise ValueError('pollard_pm1 should receive n > 3 and B > 2')
prng = random.Random(seed + B)
# computing a**lcm(1,2,3,..B) % n for B > 2
# it looks weird, but it's right: primes run [2, B]
# and the answer's not right until the loop is done.
for i in range(retries + 1):
aM = a
for p in sieve.primerange(2, B + 1):
e = int(math.log(B, p))
aM = pow(aM, pow(p, e), n)
g = igcd(aM - 1, n)
if 1 < g < n:
return int(g)
# get a new a:
# since the exponent, lcm(1..B), is even, if we allow 'a' to be 'n-1'
# then (n - 1)**even % n will be 1 which will give a g of 0 and 1 will
# give a zero, too, so we set the range as [2, n-2]. Some references
# say 'a' should be coprime to n, but either will detect factors.
a = prng.randint(2, n - 2)
def _trial(factors, n, candidates, verbose=False):
"""
Helper function for integer factorization. Trial factors ``n`
against all integers given in the sequence ``candidates``
and updates the dict ``factors`` in-place. Returns the reduced
value of ``n`` and a flag indicating whether any factors were found.
"""
if verbose:
factors0 = list(factors.keys())
nfactors = len(factors)
for d in candidates:
if n % d == 0:
m = multiplicity(d, n)
n //= d**m
factors[d] = m
if verbose:
for k in sorted(set(factors).difference(set(factors0))):
print(factor_msg % (k, factors[k]))
return int(n), len(factors) != nfactors
def _check_termination(factors, n, limitp1, use_trial, use_rho, use_pm1,
verbose):
"""
Helper function for integer factorization. Checks if ``n``
is a prime or a perfect power, and in those cases updates
the factorization and raises ``StopIteration``.
"""
if verbose:
print('Check for termination')
# since we've already been factoring there is no need to do
# simultaneous factoring with the power check
p = perfect_power(n, factor=False)
if p is not False:
base, exp = p
if limitp1:
limit = limitp1 - 1
else:
limit = limitp1
facs = factorint(base, limit, use_trial, use_rho, use_pm1,
verbose=False)
for b, e in facs.items():
if verbose:
print(factor_msg % (b, e))
factors[b] = exp*e
raise StopIteration
if isprime(n):
factors[int(n)] = 1
raise StopIteration
if n == 1:
raise StopIteration
trial_int_msg = "Trial division with ints [%i ... %i] and fail_max=%i"
trial_msg = "Trial division with primes [%i ... %i]"
rho_msg = "Pollard's rho with retries %i, max_steps %i and seed %i"
pm1_msg = "Pollard's p-1 with smoothness bound %i and seed %i"
factor_msg = '\t%i ** %i'
fermat_msg = 'Close factors satisying Fermat condition found.'
complete_msg = 'Factorization is complete.'
def _factorint_small(factors, n, limit, fail_max):
"""
Return the value of n and either a 0 (indicating that factorization up
to the limit was complete) or else the next near-prime that would have
been tested.
Factoring stops if there are fail_max unsuccessful tests in a row.
If factors of n were found they will be in the factors dictionary as
{factor: multiplicity} and the returned value of n will have had those
factors removed. The factors dictionary is modified in-place.
"""
def done(n, d):
"""return n, d if the sqrt(n) wasn't reached yet, else
n, 0 indicating that factoring is done.
"""
if d*d <= n:
return n, d
return n, 0
d = 2
m = trailing(n)
if m:
factors[d] = m
n >>= m
d = 3
if limit < d:
if n > 1:
factors[n] = 1
return done(n, d)
# reduce
m = 0
while n % d == 0:
n //= d
m += 1
if m == 20:
mm = multiplicity(d, n)
m += mm
n //= d**mm
break
if m:
factors[d] = m
# when d*d exceeds maxx or n we are done; if limit**2 is greater
# than n then maxx is set to zero so the value of n will flag the finish
if limit*limit > n:
maxx = 0
else:
maxx = limit*limit
dd = maxx or n
d = 5
fails = 0
while fails < fail_max:
if d*d > dd:
break
# d = 6*i - 1
# reduce
m = 0
while n % d == 0:
n //= d
m += 1
if m == 20:
mm = multiplicity(d, n)
m += mm
n //= d**mm
break
if m:
factors[d] = m
dd = maxx or n
fails = 0
else:
fails += 1
d += 2
if d*d > dd:
break
# d = 6*i - 1
# reduce
m = 0
while n % d == 0:
n //= d
m += 1
if m == 20:
mm = multiplicity(d, n)
m += mm
n //= d**mm
break
if m:
factors[d] = m
dd = maxx or n
fails = 0
else:
fails += 1
# d = 6*(i+1) - 1
d += 4
return done(n, d)
[docs]def factorint(n, limit=None, use_trial=True, use_rho=True, use_pm1=True,
verbose=False, visual=None):
r"""
Given a positive integer ``n``, ``factorint(n)`` returns a dict containing
the prime factors of ``n`` as keys and their respective multiplicities
as values. For example:
>>> from sympy.ntheory import factorint
>>> factorint(2000) # 2000 = (2**4) * (5**3)
{2: 4, 5: 3}
>>> factorint(65537) # This number is prime
{65537: 1}
For input less than 2, factorint behaves as follows:
- ``factorint(1)`` returns the empty factorization, ``{}``
- ``factorint(0)`` returns ``{0:1}``
- ``factorint(-n)`` adds ``-1:1`` to the factors and then factors ``n``
Partial Factorization:
If ``limit`` (> 3) is specified, the search is stopped after performing
trial division up to (and including) the limit (or taking a
corresponding number of rho/p-1 steps). This is useful if one has
a large number and only is interested in finding small factors (if
any). Note that setting a limit does not prevent larger factors
from being found early; it simply means that the largest factor may
be composite. Since checking for perfect power is relatively cheap, it is
done regardless of the limit setting.
This number, for example, has two small factors and a huge
semi-prime factor that cannot be reduced easily:
>>> from sympy.ntheory import isprime
>>> from sympy.core.compatibility import long
>>> a =<PHONE_NUMBER>262338957430697921446883
>>> f = factorint(a, limit=10000)
>>> f == {991: 1, long(202916782076162456022877024859): 1, 7: 1}
True
>>> isprime(max(f))
False
This number has a small factor and a residual perfect power whose
base is greater than the limit:
>>> factorint(3*101**7, limit=5)
{3: 1, 101: 7}
Visual Factorization:
If ``visual`` is set to ``True``, then it will return a visual
factorization of the integer. For example:
>>> from sympy import pprint
>>> pprint(factorint(4200, visual=True))
3 1 2 1
2 *3 *5 *7
Note that this is achieved by using the evaluate=False flag in Mul
and Pow. If you do other manipulations with an expression where
evaluate=False, it may evaluate. Therefore, you should use the
visual option only for visualization, and use the normal dictionary
returned by visual=False if you want to perform operations on the
factors.
You can easily switch between the two forms by sending them back to
factorint:
>>> from sympy import Mul, Pow
>>> regular = factorint(1764); regular
{2: 2, 3: 2, 7: 2}
>>> pprint(factorint(regular))
2 2 2
2 *3 *7
>>> visual = factorint(1764, visual=True); pprint(visual)
2 2 2
2 *3 *7
>>> print(factorint(visual))
{2: 2, 3: 2, 7: 2}
If you want to send a number to be factored in a partially factored form
you can do so with a dictionary or unevaluated expression:
>>> factorint(factorint({4: 2, 12: 3})) # twice to toggle to dict form
{2: 10, 3: 3}
>>> factorint(Mul(4, 12, evaluate=False))
{2: 4, 3: 1}
The table of the output logic is:
====== ====== ======= =======
Visual
------ ----------------------
Input True False other
====== ====== ======= =======
dict mul dict mul
n mul dict dict
mul mul dict dict
====== ====== ======= =======
Notes
=====
Algorithm:
The function switches between multiple algorithms. Trial division
quickly finds small factors (of the order 1-5 digits), and finds
all large factors if given enough time. The Pollard rho and p-1
algorithms are used to find large factors ahead of time; they
will often find factors of the order of 10 digits within a few
seconds:
>>> factors = factorint(12345678910111213141516)
>>> for base, exp in sorted(factors.items()):
... print('%s %s' % (base, exp))
...
2 2
2507191691 1
1231026625769 1
Any of these methods can optionally be disabled with the following
boolean parameters:
- ``use_trial``: Toggle use of trial division
- ``use_rho``: Toggle use of Pollard's rho method
- ``use_pm1``: Toggle use of Pollard's p-1 method
``factorint`` also periodically checks if the remaining part is
a prime number or a perfect power, and in those cases stops.
If ``verbose`` is set to ``True``, detailed progress is printed.
See Also
========
smoothness, smoothness_p, divisors
"""
factordict = {}
if visual and not isinstance(n, Mul) and not isinstance(n, dict):
factordict = factorint(n, limit=limit, use_trial=use_trial,
use_rho=use_rho, use_pm1=use_pm1,
verbose=verbose, visual=False)
elif isinstance(n, Mul):
factordict = dict([(int(k), int(v)) for k, v in
list(n.as_powers_dict().items())])
elif isinstance(n, dict):
factordict = n
if factordict and (isinstance(n, Mul) or isinstance(n, dict)):
# check it
for k in list(factordict.keys()):
if isprime(k):
continue
e = factordict.pop(k)
d = factorint(k, limit=limit, use_trial=use_trial, use_rho=use_rho,
use_pm1=use_pm1, verbose=verbose, visual=False)
for k, v in d.items():
if k in factordict:
factordict[k] += v*e
else:
factordict[k] = v*e
if visual or (type(n) is dict and
visual is not True and
visual is not False):
if factordict == {}:
return S.One
if -1 in factordict:
factordict.pop(-1)
args = [S.NegativeOne]
else:
args = []
args.extend([Pow(*i, evaluate=False)
for i in sorted(factordict.items())])
return Mul(*args, evaluate=False)
elif isinstance(n, dict) or isinstance(n, Mul):
return factordict
assert use_trial or use_rho or use_pm1
n = as_int(n)
if limit:
limit = int(limit)
# special cases
if n < 0:
factors = factorint(
-n, limit=limit, use_trial=use_trial, use_rho=use_rho,
use_pm1=use_pm1, verbose=verbose, visual=False)
factors[-1] = 1
return factors
if limit and limit < 2:
if n == 1:
return {}
return {n: 1}
elif n < 10:
# doing this we are assured of getting a limit > 2
# when we have to compute it later
return [{0: 1}, {}, {2: 1}, {3: 1}, {2: 2}, {5: 1},
{2: 1, 3: 1}, {7: 1}, {2: 3}, {3: 2}][n]
factors = {}
# do simplistic factorization
if verbose:
sn = str(n)
if len(sn) > 50:
print('Factoring %s' % sn[:5] + \
'..(%i other digits)..' % (len(sn) - 10) + sn[-5:])
else:
print('Factoring', n)
if use_trial:
# this is the preliminary factorization for small factors
small = 2**15
fail_max = 600
small = min(small, limit or small)
if verbose:
print(trial_int_msg % (2, small, fail_max))
n, next_p = _factorint_small(factors, n, small, fail_max)
else:
next_p = 2
if factors and verbose:
for k in sorted(factors):
print(factor_msg % (k, factors[k]))
if next_p == 0:
if n > 1:
factors[int(n)] = 1
if verbose:
print(complete_msg)
return factors
# continue with more advanced factorization methods
# first check if the simplistic run didn't finish
# because of the limit and check for a perfect
# power before exiting
try:
if limit and next_p > limit:
if verbose:
print('Exceeded limit:', limit)
_check_termination(factors, n, limit, use_trial, use_rho, use_pm1,
verbose)
if n > 1:
factors[int(n)] = 1
return factors
else:
# Before quitting (or continuing on)...
# ...do a Fermat test since it's so easy and we need the
# square root anyway. Finding 2 factors is easy if they are
# "close enough." This is the big root equivalent of dividing by
# 2, 3, 5.
sqrt_n = integer_nthroot(n, 2)[0]
a = sqrt_n + 1
a2 = a**2
b2 = a2 - n
for i in range(3):
b, fermat = integer_nthroot(b2, 2)
if fermat:
break
b2 += 2*a + 1 # equiv to (a+1)**2 - n
a += 1
if fermat:
if verbose:
print(fermat_msg)
if limit:
limit -= 1
for r in [a - b, a + b]:
facs = factorint(r, limit=limit, use_trial=use_trial,
use_rho=use_rho, use_pm1=use_pm1,
verbose=verbose)
factors.update(facs)
raise StopIteration
# ...see if factorization can be terminated
_check_termination(factors, n, limit, use_trial, use_rho, use_pm1,
verbose)
except StopIteration:
if verbose:
print(complete_msg)
return factors
# these are the limits for trial division which will
# be attempted in parallel with pollard methods
low, high = next_p, 2*next_p
limit = limit or sqrt_n
# add 1 to make sure limit is reached in primerange calls
limit += 1
while 1:
try:
high_ = high
if limit < high_:
high_ = limit
# Trial division
if use_trial:
if verbose:
print(trial_msg % (low, high_))
ps = sieve.primerange(low, high_)
n, found_trial = _trial(factors, n, ps, verbose)
if found_trial:
_check_termination(factors, n, limit, use_trial, use_rho,
use_pm1, verbose)
else:
found_trial = False
if high > limit:
if verbose:
print('Exceeded limit:', limit)
if n > 1:
factors[int(n)] = 1
raise StopIteration
# Only used advanced methods when no small factors were found
if not found_trial:
if (use_pm1 or use_rho):
high_root = max(int(math.log(high_**0.7)), low, 3)
# Pollard p-1
if use_pm1:
if verbose:
print(pm1_msg % (high_root, high_))
c = pollard_pm1(n, B=high_root, seed=high_)
if c:
# factor it and let _trial do the update
ps = factorint(c, limit=limit - 1,
use_trial=use_trial,
use_rho=use_rho,
use_pm1=use_pm1,
verbose=verbose)
n, _ = _trial(factors, n, ps, verbose=False)
_check_termination(factors, n, limit, use_trial,
use_rho, use_pm1, verbose)
# Pollard rho
if use_rho:
max_steps = high_root
if verbose:
print(rho_msg % (1, max_steps, high_))
c = pollard_rho(n, retries=1, max_steps=max_steps,
seed=high_)
if c:
# factor it and let _trial do the update
ps = factorint(c, limit=limit - 1,
use_trial=use_trial,
use_rho=use_rho,
use_pm1=use_pm1,
verbose=verbose)
n, _ = _trial(factors, n, ps, verbose=False)
_check_termination(factors, n, limit, use_trial,
use_rho, use_pm1, verbose)
except StopIteration:
if verbose:
print(complete_msg)
return factors
low, high = high, high*2
def factorrat(rat, limit=None, use_trial=True, use_rho=True, use_pm1=True,
verbose=False, visual=None):
r"""
Given a Rational ``r``, ``factorrat(r)`` returns a dict containing
the prime factors of ``r`` as keys and their respective multiplicities
as values. For example:
>>> from sympy.ntheory import factorrat
>>> from sympy.core.symbol import S
>>> factorrat(S(8)/9) # 8/9 = (2**3) * (3**-2)
{2: 3, 3: -2}
>>> factorrat(S(-1)/987) # -1/789 = -1 * (3**-1) * (7**-1) * (47**-1)
{-1: 1, 3: -1, 7: -1, 47: -1}
Please see the docstring for ``factorint`` for detailed explanations
and examples of the following keywords:
- ``limit``: Integer limit up to which trial division is done
- ``use_trial``: Toggle use of trial division
- ``use_rho``: Toggle use of Pollard's rho method
- ``use_pm1``: Toggle use of Pollard's p-1 method
- ``verbose``: Toggle detailed printing of progress
- ``visual``: Toggle product form of output
"""
from collections import defaultdict
f = factorint(rat.p, limit=limit, use_trial=use_trial,
use_rho=use_rho, use_pm1=use_pm1,
verbose=verbose).copy()
f = defaultdict(int, f)
for p, e in factorint(rat.q, limit=limit,
use_trial=use_trial,
use_rho=use_rho,
use_pm1=use_pm1,
verbose=verbose).items():
f[p] += -e
if len(f) > 1 and 1 in f:
del f[1]
if not visual:
return dict(f)
else:
if -1 in f:
f.pop(-1)
args = [S.NegativeOne]
else:
args = []
args.extend([Pow(*i, evaluate=False)
for i in sorted(f.items())])
return Mul(*args, evaluate=False)
[docs]def primefactors(n, limit=None, verbose=False):
"""Return a sorted list of n's prime factors, ignoring multiplicity
and any composite factor that remains if the limit was set too low
for complete factorization. Unlike factorint(), primefactors() does
not return -1 or 0.
Examples
========
>>> from sympy.ntheory import primefactors, factorint, isprime
>>> primefactors(6)
[2, 3]
>>> primefactors(-5)
[5]
>>> sorted(factorint(123456).items())
[(2, 6), (3, 1), (643, 1)]
>>> primefactors(123456)
[2, 3, 643]
>>> sorted(factorint(10000000001, limit=200).items())
[(101, 1), (99009901, 1)]
>>> isprime(99009901)
False
>>> primefactors(10000000001, limit=300)
[101]
See Also
========
divisors
"""
n = int(n)
factors = sorted(factorint(n, limit=limit, verbose=verbose).keys())
s = [f for f in factors[:-1:] if f not in [-1, 0, 1]]
if factors and isprime(factors[-1]):
s += [factors[-1]]
return s
def _divisors(n):
"""Helper function for divisors which generates the divisors."""
factordict = factorint(n)
ps = sorted(factordict.keys())
def rec_gen(n=0):
if n == len(ps):
yield 1
else:
pows = [1]
for j in range(factordict[ps[n]]):
pows.append(pows[-1] * ps[n])
for q in rec_gen(n + 1):
for p in pows:
yield p * q
for p in rec_gen():
yield p
[docs]def divisors(n, generator=False):
r"""
Return all divisors of n sorted from 1..n by default.
If generator is ``True`` an unordered generator is returned.
The number of divisors of n can be quite large if there are many
prime factors (counting repeated factors). If only the number of
factors is desired use divisor_count(n).
Examples
========
>>> from sympy import divisors, divisor_count
>>> divisors(24)
[1, 2, 3, 4, 6, 8, 12, 24]
>>> divisor_count(24)
8
>>> list(divisors(120, generator=True))
[1, 2, 4, 8, 3, 6, 12, 24, 5, 10, 20, 40, 15, 30, 60, 120]
This is a slightly modified version of Tim Peters referenced at:
http://stackoverflow.com/questions/1010381/python-factorization
See Also
========
primefactors, factorint, divisor_count
"""
n = as_int(abs(n))
if isprime(n):
return [1, n]
if n == 1:
return [1]
if n == 0:
return []
rv = _divisors(n)
if not generator:
return sorted(rv)
return rv
[docs]def divisor_count(n, modulus=1):
"""
Return the number of divisors of ``n``. If ``modulus`` is not 1 then only
those that are divisible by ``modulus`` are counted.
References
==========
- http://www.mayer.dial.pipex.com/maths/formulae.htm
>>> from sympy import divisor_count
>>> divisor_count(6)
4
See Also
========
factorint, divisors, totient
"""
if not modulus:
return 0
elif modulus != 1:
n, r = divmod(n, modulus)
if r:
return 0
if n == 0:
return 0
return Mul(*[v + 1 for k, v in factorint(n).items() if k > 1])
def _udivisors(n):
"""Helper function for udivisors which generates the unitary divisors."""
factorpows = [p**e for p, e in factorint(n).items()]
for i in range(2**len(factorpows)):
d, j, k = 1, i, 0
while j:
if (j & 1):
d *= factorpows[k]
j >>= 1
k += 1
yield d
[docs]def udivisors(n, generator=False):
r"""
Return all unitary divisors of n sorted from 1..n by default.
If generator is ``True`` an unordered generator is returned.
The number of unitary divisors of n can be quite large if there are many
prime factors. If only the number of unitary divisors is desired use
udivisor_count(n).
References
==========
- http://en.wikipedia.org/wiki/Unitary_divisor
- http://mathworld.wolfram.com/UnitaryDivisor.html
Examples
========
>>> from sympy.ntheory.factor_ import udivisors, udivisor_count
>>> udivisors(15)
[1, 3, 5, 15]
>>> udivisor_count(15)
4
>>> sorted(udivisors(120, generator=True))
[1, 3, 5, 8, 15, 24, 40, 120]
See Also
========
primefactors, factorint, divisors, divisor_count, udivisor_count
"""
n = as_int(abs(n))
if isprime(n):
return [1, n]
if n == 1:
return [1]
if n == 0:
return []
rv = _udivisors(n)
if not generator:
return sorted(rv)
return rv
[docs]def udivisor_count(n):
"""
Return the number of unitary divisors of ``n``.
References
==========
- http://mathworld.wolfram.com/UnitaryDivisorFunction.html
>>> from sympy.ntheory.factor_ import udivisor_count
>>> udivisor_count(120)
8
See Also
========
factorint, divisors, udivisors, divisor_count, totient
"""
if n == 0:
return 0
return 2**len([p for p in factorint(n) if p > 1])
def _antidivisors(n):
"""Helper function for antidivisors which generates the antidivisors."""
for d in _divisors(n):
y = 2*d
if n > y and n % y:
yield y
for d in _divisors(2*n-1):
if n > d >= 2 and n % d:
yield d
for d in _divisors(2*n+1):
if n > d >= 2 and n % d:
yield d
[docs]def antidivisors(n, generator=False):
r"""
Return all antidivisors of n sorted from 1..n by default.
Antidivisors [1]_ of n are numbers that do not divide n by the largest
possible margin. If generator is True an unordered generator is returned.
References
==========
.. [1] definition is described in http://oeis.org/A066272/a066272a.html
Examples
========
>>> from sympy.ntheory.factor_ import antidivisors
>>> antidivisors(24)
[7, 16]
>>> sorted(antidivisors(128, generator=True))
[3, 5, 15, 17, 51, 85]
See Also
========
primefactors, factorint, divisors, divisor_count, antidivisor_count
"""
n = as_int(abs(n))
if n <= 2:
return []
rv = _antidivisors(n)
if not generator:
return sorted(rv)
return rv
[docs]def antidivisor_count(n):
"""
Return the number of antidivisors [1]_ of ``n``.
References
==========
.. [1] formula from https://oeis.org/A066272
Examples
========
>>> from sympy.ntheory.factor_ import antidivisor_count
>>> antidivisor_count(13)
4
>>> antidivisor_count(27)
5
See Also
========
factorint, divisors, antidivisors, divisor_count, totient
"""
n = as_int(abs(n))
if n <= 2:
return 0
return divisor_count(2*n-1) + divisor_count(2*n+1) + \
divisor_count(n) - divisor_count(n, 2) - 5
[docs]class totient(Function):
"""
Calculate the Euler totient function phi(n)
>>> from sympy.ntheory import totient
>>> totient(1)
1
>>> totient(25)
20
See Also
========
divisor_count
"""
@classmethod
def eval(cls, n):
n = sympify(n)
if n.is_Integer:
if n < 1:
raise ValueError("n must be a positive integer")
factors = factorint(n)
t = 1
for p, k in factors.items():
t *= (p - 1) * p**(k - 1)
return t
def _eval_is_integer(self):
return fuzzy_and([self.args[0].is_integer, self.args[0].is_positive])
[docs]class divisor_sigma(Function):
"""
Calculate the divisor function `\sigma_k(n)` for positive integer n
``divisor_sigma(n, k)`` is equal to ``sum([x**k for x in divisors(n)])``
If n's prime factorization is:
.. math ::
n = \prod_{i=1}^\omega p_i^{m_i},
then
.. math ::
\sigma_k(n) = \prod_{i=1}^\omega (1+p_i^k+p_i^{2k}+\cdots
+ p_i^{m_ik}).
Parameters
==========
k : power of divisors in the sum
for k = 0, 1:
``divisor_sigma(n, 0)`` is equal to ``divisor_count(n)``
``divisor_sigma(n, 1)`` is equal to ``sum(divisors(n))``
Default for k is 1.
References
==========
.. [1] http://en.wikipedia.org/wiki/Divisor_function
Examples
========
>>> from sympy.ntheory import divisor_sigma
>>> divisor_sigma(18, 0)
6
>>> divisor_sigma(39, 1)
56
>>> divisor_sigma(12, 2)
210
>>> divisor_sigma(37)
38
See Also
========
divisor_count, totient, divisors, factorint
"""
@classmethod
def eval(cls, n, k=1):
n = sympify(n)
k = sympify(k)
if n.is_prime:
return 1 + n**k
if n.is_Integer:
if n <= 0:
raise ValueError("n must be a positive integer")
else:
return Mul(*[(p**(k*(e + 1)) - 1)/(p**k - 1) if k != 0
else e + 1 for p, e in factorint(n).items()])
[docs]def core(n, t=2):
"""
Calculate core(n,t) = `core_t(n)` of a positive integer n
``core_2(n)`` is equal to the squarefree part of n
If n's prime factorization is:
.. math ::
n = \prod_{i=1}^\omega p_i^{m_i},
then
.. math ::
core_t(n) = \prod_{i=1}^\omega p_i^{m_i \mod t}.
Parameters
==========
t : core(n,t) calculates the t-th power free part of n
``core(n, 2)`` is the squarefree part of ``n``
``core(n, 3)`` is the cubefree part of ``n``
Default for t is 2.
References
==========
.. [1] http://en.wikipedia.org/wiki/Square-free_integer#Squarefree_core
Examples
========
>>> from sympy.ntheory.factor_ import core
>>> core(24, 2)
6
>>> core(9424, 3)
1178
>>> core(379238)
379238
>>> core(15**11, 10)
15
See Also
========
factorint, sympy.solvers.diophantine.square_factor
"""
n = as_int(n)
t = as_int(t)
if n <= 0:
raise ValueError("n must be a positive integer")
elif t <= 1:
raise ValueError("t must be >= 2")
else:
y = 1
for p, e in factorint(n).items():
y *= p**(e % t)
return y
[docs]def digits(n, b=10):
"""
Return a list of the digits of n in base b. The first element in the list
is b (or -b if n is negative).
Examples
========
>>> from sympy.ntheory.factor_ import digits
>>> digits(35)
[10, 3, 5]
>>> digits(27, 2)
[2, 1, 1, 0, 1, 1]
>>> digits(65536, 256)
[256, 1, 0, 0]
>>> digits(-3958, 27)
[-27, 5, 11, 16]
"""
b = as_int(b)
n = as_int(n)
if b <= 1:
raise ValueError("b must be >= 2")
else:
x, y = abs(n), []
while x >= b:
x, r = divmod(x, b)
y.append(r)
y.append(x)
y.append(-b if n < 0 else b)
y.reverse()
return y
[docs]class udivisor_sigma(Function):
"""
Calculate the unitary divisor function `\sigma_k^*(n)` for positive integer n
``udivisor_sigma(n, k)`` is equal to ``sum([x**k for x in udivisors(n)])``
If n's prime factorization is:
.. math ::
n = \prod_{i=1}^\omega p_i^{m_i},
then
.. math ::
\sigma_k^*(n) = \prod_{i=1}^\omega (1+ p_i^{m_ik}).
Parameters
==========
k : power of divisors in the sum
for k = 0, 1:
``udivisor_sigma(n, 0)`` is equal to ``udivisor_count(n)``
``udivisor_sigma(n, 1)`` is equal to ``sum(udivisors(n))``
Default for k is 1.
References
==========
.. [1] http://mathworld.wolfram.com/UnitaryDivisorFunction.html
Examples
========
>>> from sympy.ntheory.factor_ import udivisor_sigma
>>> udivisor_sigma(18, 0)
4
>>> udivisor_sigma(74, 1)
114
>>> udivisor_sigma(36, 3)
47450
>>> udivisor_sigma(111)
152
See Also
========
divisor_count, totient, divisors, udivisors, udivisor_count, divisor_sigma,
factorint
"""
@classmethod
def eval(cls, n, k=1):
n = sympify(n)
k = sympify(k)
if n.is_prime:
return 1 + n**k
if n.is_Integer:
if n <= 0:
raise ValueError("n must be a positive integer")
else:
return Mul(*[1+p**(k*e) for p, e in factorint(n).items()])


The following people are involved in the SEAM project:
There are also several students working within the project:
Please send comments or suggestions to:


Type an address, then press Enter (or Tab).
Press Esc to clear the textbox (will be fired onClear event).
example: 1600 Amphitheatre Parkway, Mountain View


--- layout: post title: "What Is Regularization In Machine Learning?" subtitle: "Solving overfitting problem with regularization" date: 2018-03-10 00:00:60 -0000 background: '/img/posts/06.jpg' tags: [Machine Learning, ML, AI, Deep Learning, Neural Network, Artificial Intelligence, Regularization, Lasso, Ridge, L1, L2] ---
Regularization is a technique which is used to solve the overfitting problem of the machine learning models.
Overfitting is a phenomenon which occurs when a model learns the detail and noise in the training data to an extent that it negatively impacts the performance of the model on new data.
So the overfitting is a major problem as it negatively impacts the performance.
Regularization technique to the rescue.
Generally, a good model does not give more weight to a particular feature. The weights are evenly distributed. This can be achieved by doing regularization.
There are two types of regularization as follows:
L1 Regularization or Lasso Regularization adds a penalty to the error function. The penalty is the sum of the absolute values of weights.
p
is the tuning parameter which decides how much we want to penalize the model.
L2 Regularization or Ridge Regularization also adds a penalty to the error function. But the penalty here is the sum of the squared values of weights.
Similar to L1, in L2 also, p
is the tuning parameter which decides how much we want to penalize the model.
This is Regularization. That's it for now.


| HBASE-10922 |
Log splitting status should always be closed |
Minor |
wal |
Jimmy Xiang |
Jeffrey Zhong |
| HBASE-11302 |
ReplicationSourceManager#sources is not thread safe |
Major |
Replication |
Qianxi Zhang |
Qianxi Zhang |
| HBASE-11311 |
Secure Bulk Load does not execute chmod 777 on the files |
Major |
security |
Matteo Bertozzi |
Matteo Bertozzi |
| HBASE-11312 |
Minor refactoring of TestVisibilityLabels class |
Trivial |
security |
Srikanth Srungarapu |
Srikanth Srungarapu |
| HBASE-11310 |
Delete's copy constructor should copy the attributes also |
Major |
mapreduce |
ramkrishna.s.vasudevan |
ramkrishna.s.vasudevan |
| HBASE-11327 |
ExportSnapshot hit stackoverflow error when target snapshotDir doesn't contain uri |
Minor |
snapshots |
Demai Ni |
Demai Ni |
| HBASE-11162 |
RegionServer webui uses the default master info port irrespective of the user configuration. |
Minor |
UI |
Srikanth Srungarapu |
Srikanth Srungarapu |
| HBASE-11342 |
The method isChildReadLock in class ZKInterProcessLockBase is wrong |
Minor |
Zookeeper |
Qianxi Zhang |
Qianxi Zhang |
| HBASE-11347 |
For some errors, the client can retry infinitely |
Critical |
Client |
Nicolas Liochon |
Nicolas Liochon |
| HBASE-11353 |
Wrong Write Request Count |
Major |
regionserver |
Nicolas Liochon |
Nicolas Liochon |
| HBASE-11194 |
[AccessController] issue with covering permission check in case of concurrent op on same row |
Major |
security |
Anoop Sam John |
Anoop Sam John |
| HBASE-11341 |
ZKProcedureCoordinatorRpcs should respond only to members |
Minor |
. |
Matteo Bertozzi |
Matteo Bertozzi |
| HBASE-11371 |
Typo in Thrift2 docs |
Trivial |
documentation |
Cesar Delgado |
Cesar Delgado |
| HBASE-11052 |
Sending random data crashes thrift service |
Major |
Thrift |
Adrian Muraru |
Adrian Muraru |
| HBASE-11378 |
TableMapReduceUtil overwrites user supplied options for multiple tables/scaners job |
Major |
. |
Jimmy Xiang |
Jimmy Xiang |
| HBASE-11374 |
RpcRetryingCaller#callWithoutRetries has a timeout of zero |
Critical |
Client |
Nicolas Liochon |
Nicolas Liochon |
| HBASE-11387 |
metrics: wrong totalRequestCount |
Major |
metrics, regionserver |
Nicolas Liochon |
Nicolas Liochon |
| HBASE-11380 |
HRegion lock object is not being released properly, leading to snapshot failure |
Blocker |
regionserver |
Craig Condit |
Ted Yu |
| HBASE-11403 |
Fix race conditions around Object#notify |
Major |
Client, regionserver |
Nicolas Liochon |
Nicolas Liochon |
| HBASE-11396 |
Invalid meta entries can lead to unstartable master |
Major |
master |
Craig Condit |
|
| HBASE-11363 |
Access checks in preCompact and preCompactSelection are out of sync |
Major |
. |
Andrew Purtell |
Andrew Purtell |
| HBASE-11391 |
Thrift table creation will fail with default TTL with sanity checks |
Major |
. |
Enis Soztutar |
Enis Soztutar |
| HBASE-11397 |
When merging expired stripes, we need to create an empty file to preserve metadata. |
Major |
Compaction |
Victor Xu |
Victor Xu |
| HBASE-11418 |
build target "site" doesn't respect hadoop-two.version property |
Major |
build |
Konstantin Boudnik |
Konstantin Boudnik |
| HBASE-11424 |
Avoid usage of CellUtil#getTagArray(Cell cell) within server |
Major |
. |
Anoop Sam John |
Anoop Sam John |
| HBASE-11430 |
lastFlushSeqId has been updated wrongly during region open |
Major |
MTTR |
Jeffrey Zhong |
Jeffrey Zhong |
| HBASE-10330 |
TableInputFormat/TableRecordReaderImpl leaks HTable |
Blocker |
. |
G G |
Ted Yu |
| HBASE-11433 |
LruBlockCache does not respect its configurable parameters |
Major |
regionserver |
Shengzhe Yao |
Shengzhe Yao |
| HBASE-11335 |
Fix the TABLE_DIR param in TableSnapshotInputFormat |
Major |
mapreduce, snapshots |
deepankar |
|
| HBASE-11435 |
Visibility labelled cells fail to getting replicated |
Critical |
Replication, security |
Anoop Sam John |
Anoop Sam John |
| HBASE-11439 |
StripeCompaction may not obey the OffPeak rule to compaction |
Minor |
Compaction |
Victor Xu |
Victor Xu |
| HBASE-11432 |
[AccessController] Remove cell first strategy |
Major |
. |
Andrew Purtell |
Andrew Purtell |
| HBASE-11413 |
[findbugs] RV: Negating the result of compareTo()/compare() |
Trivial |
. |
Mike Drob |
Mike Drob |
| HBASE-11294 |
IntegrationTestIngestWithACL should automatically set the superuser when running on local minicluster |
Major |
. |
Andrew Purtell |
ramkrishna.s.vasudevan |
| HBASE-11422 |
Specification of scope is missing for certain Hadoop dependencies |
Major |
. |
Ted Yu |
Konstantin Boudnik |
| HBASE-11457 |
Increment HFile block encoding IVs accounting for ciper's internal use |
Major |
. |
Andrew Purtell |
Andrew Purtell |
| HBASE-11465 |
[VisibilityController] Reserved tags check not happening for Append/Increment |
Major |
security |
Anoop Sam John |
Anoop Sam John |
| HBASE-11458 |
NPEs if RegionServer cannot initialize |
Major |
. |
Enis Soztutar |
Enis Soztutar |
| HBASE-11481 |
TableSnapshotInputFormat javadoc wrongly claims HBase "enforces security" |
Minor |
. |
Andrew Purtell |
Andrew Purtell |
| HBASE-11475 |
Distributed log replay should also replay compaction events |
Major |
. |
Enis Soztutar |
Enis Soztutar |
| HBASE-11496 |
HBASE-9745 broke cygwin CLASSPATH translation |
Minor |
. |
Dave Latham |
Dave Latham |
| HBASE-11423 |
Visibility label and per cell ACL feature not working with HTable#mutateRow() and MultiRowMutationEndpoint |
Blocker |
Coprocessors, security |
Anoop Sam John |
Anoop Sam John |
| HBASE-11487 |
ScanResponse carries non-zero cellblock for CloseScanRequest (ScanRequest with close_scanner = true) |
Minor |
IPC/RPC, regionserver |
Shengzhe Yao |
Shengzhe Yao |
| HBASE-11460 |
Deadlock in HMaster on masterAndZKLock in HConnectionManager |
Critical |
master |
Andrey Stepachev |
Ted Yu |
| HBASE-11488 |
cancelTasks in SubprocedurePool can hang during task error |
Minor |
snapshots |
Jerry He |
Jerry He |
| HBASE-11118 |
non environment variable solution for "IllegalAccessError: class com.google.protobuf.ZeroCopyLiteralByteString cannot access its superclass com.google.protobuf.LiteralByteString" |
Blocker |
mapreduce |
André Kelpe |
stack |
| HBASE-11493 |
Autorestart option is not working because of stale znode "shutdown" |
Major |
. |
Nishan Shetty |
nijel |
| HBASE-11506 |
IntegrationTestWithCellVisibilityLoadAndVerify allow User to be passed as arg |
Major |
. |
ramkrishna.s.vasudevan |
ramkrishna.s.vasudevan |
| HBASE-11505 |
'snapshot' shell command shadows 'snapshot' shell when 'help' is invoked |
Trivial |
shell |
Nick Dimiduk |
Nick Dimiduk |
| HBASE-11510 |
Visibility serialization format tag gets duplicated in Append/Increment'ed cells |
Major |
security |
Anoop Sam John |
Anoop Sam John |
| HBASE-11442 |
ReplicationSourceManager doesn't cleanup the queues for recovered sources |
Major |
Replication |
Virag Kothari |
Virag Kothari |
| HBASE-11492 |
Hadoop configuration overrides some ipc parameters including tcpNoDelay |
Critical |
regionserver |
Nicolas Liochon |
Nicolas Liochon |


@t header
%fn_introfn main() { println('hello world' ) }
println('hello world' )
// This is a single line comment. /* This is a multiline comment. /* It can be nested. */ */
fn main() { println(add(77, 33)) println(sub(100, 50)) }fn add(x int, y int) int { return x + y }fn sub(x, y int) int { return x - y }
Again, the type comes after the argument's name.
Just like in Go and C, functions cannot be overloaded. This simplifies the code and improves maintainability and readability.
Functions can be used before their declaration:
add
and sub
are declared after main
, but
can still be called from main
.
This is true for all declarations in V and eliminates the need of header files
or thinking about the order of files and declarations.
fn foo() (int, int) { return 2, 3 } a, b := foo() println(a) // 2 println(b) // 3
Functions can return multiple values.
Functions, like consts, and types, are private (not exported) by default.
To allow other modules to use them, prepend pub
. The same applies
to consts and types.
pub fn public_function() { } fn private_function() { }
name :='Bob' age := 20 large_number := i64(9999999999) println(name) println(age) println(large_number)
Variables are declared and initialized with :=
. This is the only
way to declare variables in V. This means that variables always have an initial
value.
The variable's type is inferred from the value on the right hand side.
To force a different type, use type conversion:
the expression T(v)
converts the value v
to the
type T
.
Unlike most other languages, V only allows defining variables in functions. Global (module level) variables are not allowed. There's no global state in V.
mut age := 20 println(age) age = 21 println(age)
To change the value of the variable use =
. In V, variables are
immutable by default. To be able to change the value of the variable, you
have to declare it with mut
.
Try compiling the program above after removing mut
from
the first line.
Please note the difference between :=
and =
:=
is used for declaring and initializing, =
is used for assigning.
fn main() { age = 21 }
This code will not compile, because variable age
is not declared.
All variables need to be declared in V.
fn main() { age := 21 }
In development mode this code will result in an "unused variable" warning.
In production mode (v -prod foo.v
) it will not compile at all, like
in Go.
fn main() { a := 10 if true { a := 20 } }
Unlike most languages, variable shadowing is not allowed. Declaring a variable with a name that is already used in a parent scope will result in a compilation error.
bool string i8 i16 int i64 i128 (soon) byte u16 u32 u64 u128 (soon) runePlease note that unlike C and Go,// represents a Unicode code point f32 f64 byteptr voidptr
int
is always a 32 bit integer.
name :='Bob' println('Hello, $name!' )// `$` is used for string interpolation println(name.len) bobby := name +'by' // + is used to concatenate strings println(bobby)// "Bobby" println(bobby[1..3])// "ob" mut s :='hello ' s +='world' // `+=` is used to append to a string println(s)// "hello world"
In V, a string is a read-only array of bytes. String data is encoded using UTF-8.
Strings are immutable.
Both single and double quotes can be used to denote strings. For consistency, vfmt
converts double quotes to single quotes unless the string
contains a single quote character.
Interpolation syntax is pretty simple. It also works with fields:
'age = $user.age'
. If you need more complex expressions, use
${}
: 'can register = ${user.age > 13}'
.
All operators in V must have values of the same type on both sides.
This code will not compile if age
is an int
:
println(We have to either convert'age = ' + age)
age
to a string
:
println(or use string interpolation (preferred):'age = ' + age.str())
println('age = $age' )
To denote character literals, use `
a := `a` assert 'aloha!'[0] == `a`
For raw strings, prepend r
. Raw strings are not escaped:
s :=r'hello\nworld' println(s) // "hello\nworld"
mut nums := [1, 2, 3] println(nums)// "[1, 2, 3]" println(nums[1])// "2" nums << 4 println(nums)// "[1, 2, 3, 4]" nums << [5, 6, 7] println(nums)// "[1, 2, 3, 4, 5, 6, 7]" mut names := ['John' ] names <<'Peter' names <<'Sam' // names << 10 <-- This will not compile. `names` is an array of strings. println(names.len)// "3" println('Alex' in names)// "false" names = []// The array is now empty // We can also preallocate a certain amount of elements. ids := [0].repeat(50)// This creates an array with 50 zeros
Array type is determined by the first element: [1, 2, 3]
is an array of ints
([]int
).
['a', 'b']
is an array of strings ([]string
).
All elements must have the same type. [1, 'a']
will not compile.
<<
is an operator that appends a value to the end of the array.
It can also append an entire array.
.len
field returns the length of the array. Note, that it's a read-only field,
and it can't be modified by the user. All exported fields are read-only by default in V.
val in array
returns true if the array contains val
.
All arrays can be easily printed with println(arr)
and converted to a string
with s := arr.str()
.
Arrays can be efficiently filtered and mapped with .filter()
and
.map()
methods:
nums := [1, 2, 3, 4, 5, 6] even := nums.filter(it % 2 == 0) println(even) // [2, 4, 6] words := ['hello', 'world'] upper := words.map(it.to_upper()) println(upper) // ['HELLO', 'WORLD']
it
is a special variable that refers to an element in filter/map
methods.
mut m := map[string]int// Only maps with string keys are allowed for now m['one' ] = 1 m['two' ] = 2 println(m['one' ])// "1" println(m['bad_key' ])// "0" println('bad_key' in m)// Use `in` to detect whether such key exists m.delete('two' ) numbers := {'one' : 1,'two' : 2, }
a := 10 b := 20if a < b { println('$a < $b' ) }else if a > b { println('$a > $b' ) }else { println('$a == $b' ) }
if
statements are pretty straightforward and similar to most
other languages.
Unlike other C-like languages, there are no parentheses surrounding the condition, and the braces are always required.
if
can be used as an expression:
num := 777 s :=if num % 2 == 0 {'even' }else {'odd' } println(s)// "odd"
in
allows to check whether an array or a map contains an element.
nums := [1, 2, 3] println(1It's also useful for writing more clear and compact boolean expressions:in nums)// true m := {'one': 1, 'two': 2} println('one'in m)// true
V optimizes such expressions, so bothif parser.token == .plus || parser.token == .minus || parser.token == .div || parser.token == .mult { ... }if parser.tokenin [.plus, .minus, .div, .mult] { ... }
if
statements above produce the same machine code,
no arrays are created.
for
.
numbers := [1, 2, 3, 4, 5]for numin numbers { println(num) } names := ['Sam' ,'Peter' ]for i, namein names { println('$i) $name' )// Output: 0) Sam }// 1) Peter
The for value in
loop is used for going through elements of an array.
If an index is required, an alternative form for index, value in
can be used.
Note, that the value is read-only. If you need to modify the array while looping, you have to use indexing:
mut numbers := [1, 2, 3, 4, 5]for i, numin numbers { println(num) numbers[i] = 0 }
mut sum := 0 mut i := 0 for i <= 100 { sum += i i++ } println(sum) // "5050"
This form of the loop is similar to while
loops in other languages.
The loop will stop iterating once the boolean condition evaluates to false.
Again, there are no parentheses surrounding the condition, and the braces are always required.
mut num := 0 for { num++if num >= 10 { break } } println(num) // "10"
The condition can be omitted, this results in an infinite loop.
for i := 0; i < 10; i++ {// Don't print 6 if i == 6 { continue } println(i) }
Finally, there's the traditional C style for
loop. It's safer than the `while` form
because with the latter it's easy to forget to update the counter and get
stuck in an infinite loop.
Here i
doesn't need to be declared with mut
since it's always going to be mutable by definition.
os := 'windows' print('V is running on ') match os { 'darwin' { println('macOS.') } 'linux' { println('Linux.') } else { println(os) } } s := match number { 1 { 'one' } 2 { 'two' } else { println('this works too') 'many' } }
A match statement is a shorter way to write a sequence of if - else
statements. When a matching branch is found, the following statement block will be run, and the final expression will be returned. The else branch will be evaluated when no other branches match.
enum Color { red blue green } fn is_red_or_blue(c Color) bool { return match c { .red { true } .blue { true } else { false } } }
A match statement can also be used to branch on the variants of an enum
by using the shorthand .variant_here
syntax.
struct Point { x int y int } p := Point{ x: 10 y: 20 } println(p.x)// Struct fields are accessed using a dot
Structs are allocated on the stack. To allocate a struct on the heap and get
a reference to it, use the &
prefix:
// Alternative initialization syntax for structs with 3 fields or fewer p := &Point{10, 10}// References have the same syntax for accessing fields println(p.x)
The type of p
is &Point
. It's a reference to
Point
. References are similar
to Go pointers and C++ references.
V doesn't have subclassing, but it supports embedded structs:
// TODO: this will be implemented later struct Button { Widget title string } button := new_button('Click me' ) button.set_pos(x, y)// Without embedding we'd have to do button.widget.set_pos(x,y)
Structs can have default values:
struct Foo { a int b int = 10 } foo := Foo{} assert foo.a == 0 assert foo.b == 10
Struct fields are private and immutable by default (making structs immutable as well).
Their access modifiers can be changed with
pub
and mut
. In total, there are 5 possible options:
struct Foo { a int// private immutable (default) mut : b int// private mutable c int// (you can list multiple fields with the same access modifier) pub : d int// public immmutable (readonly) pub mut : e int// public, but mutable only in parent module __global : f int// public and mutable both inside and outside parent module }// (not recommended to use, that's why the 'global' keyword // starts with __)
For example, here's the string
type defined in the builtin
module:
struct string { str byteptrpub : len int }
It's easy to see from this definition that
string
is an immutable type.
The byte pointer with the string data is not accessible outside builtin
at all.
len
field is public, but not mutable:
fn main() { str :='hello' len := str.len// OK str.len++// Compilation error }
struct User { age int }fn (u User) can_register() bool { return u.age > 16 } user := User{age: 10} println(user.can_register())// "false" user2 := User{age: 20} println(user2.can_register())// "true"
V doesn't have classes. But you can define methods on types.
A method is a function with a special receiver argument.
The receiver appears in its own argument list between the fn
keyword and the method name.
In this example, the can_register
method has a receiver of type User
named u
. The convention is not to use receiver names like self
or
this
, but a short, preferably one letter long, name.
This is achieved by lack of global variables and all function arguments being immutable by default, even when references are passed.
V is not a pure functional language however. It is possible to modify function arguments
by using the same keyword mut
:
struct User {mut : is_registered bool }fn (umut User) register() { u.is_registered = true }mut user := User{} println(user.is_registered)// "false" user.register() println(user.is_registered)// "true"
In this example, the receiver (which is simply the first argument) is marked as mutable,
so register()
can change the user object.
The same works with non-receiver arguments:
fn multiply_by_2(arrmut []int) {for i := 0; i < arr.len; i++ { arr[i] *= 2 } }mut nums := [1, 2, 3] multiply_by_2(mut nums) println(nums)// "[2, 4, 6]"
Note, that you have to add mut
before nums
when calling this function. This makes
it clear that the function being called will modify the value.
It is preferable to return values instead of modifying arguments. Modifying arguments should only be done in performance-critical parts of your application to reduce allocations and copying.
For this reason V doesn't allow to modify primitive args like integers, only complex types like arrays and maps.
Use user.register()
or user = register(user)
instead of register(mut user)
.
V makes it easy to return a modified version of an object:
fn register(u User) User { return { u | is_registered: true } } user = register(user)
fn sqr(n int) int { return n * n } fn run(value int, op fn(int) int) int { return op(value) } fn main() { println(run(5, sqr))// "25" }
fn (foo Foo) bar_method() { ... } fn bar_function(foo Foo) { ... }If a function argument is immutable like
foo
in the examples above,
V can pass it by value or by reference. The decision is made
by the compiler, and the developer doesn't need to think about it.
You no longer need to remember whether you should pass the struct by value or by reference.
There's a way to ensure that the struct is always passed by reference by
adding &
:
fn (foo &Foo) bar() { println(foo.abc) }
foo
is still immutable and can't be changed. For that,
(foo mut Foo)
has to be used.
In general, V references are similar to Go pointers and C++ references. For example, a tree structure definition would look like this:
struct Node<T> { val T left &Node right &Node }
const ( pi = 3.14 world ='世界' ) println(pi) println(world)
Constants are declared with const
. They can only be defined
at the module level (outside of functions).
Constant values can never be changed.
V constants are more flexible than in most languages. You can assign more complex values:
struct Color { r int g int b int }fn (c Color) str() string { return'{$c.r, $c.g, $c.b}' }fn rgb(r, g, b int) Color { return Color{r: r, g: g, b: b} }const ( numbers = [1, 2, 3] red = Color{r: 255, g: 0, b: 0} blue = rgb(0, 0, 255) ) println(numbers) println(red) println(blue)
Global variables are not allowed, so this can be really useful.
When naming constants, snake_case must be used.
Many people prefer all caps consts: TOP_CITIES
. This wouldn't work
well in V, because consts are a lot more powerful than in other languages.
They can represent complex structures, and this is used quite often since there
are no globals:
println('Top cities: $TOP_CITIES.filter(.usa)' ) vs println('Top cities: $top_cities.filter(.usa)' )
println
is a simple yet powerful builtin function. It can print anything:
strings, numbers, arrays, maps, structs.
println(1)If you want to define a custom print value for your type, simply define a// "1" println('hi')// "hi" println([1,2,3])// "[1, 2, 3]" println(User{name:'Bob', age:20})// "User{name:'Bob', age:20}"
.str() string
method.
If you don't want to print a newline, use print()
instead.
cd ~/code/modules mkdir mymodule vim mymodule/mymodule.vYou can have as many .v files in// mymodule.v module mymodule// To export a function we have to use `pub` pub fn say_hi() { println('hello from mymodule!' ) }
mymodule/
as you want.
Build it with v build module ~/code/modules/mymodule
.
That's it, you can now use it in your code:
module mainimport mymodulefn main() { mymodule.say_hi() }
Note that you have to specify the module every time you call an external function. This may seem verbose at first, but it makes code much more readable and easier to understand, since it's always clear which function from which module is being called. Especially in large code bases.
Module names should be short, under 10 characters. Circular imports are not allowed.
You can create modules anywhere.
All modules are compiled statically into a single executable.
If you want to write a module that will automatically call some
setup/initialization code when imported (perhaps you want to call
some C library functions), write a module init
function inside the module:
fn init() { // your setup code here ... }
The init function cannot be public. It will be called automatically.
struct Dog {}struct Cat {}fn (d Dog) speak() string { return'woof' }fn (c Cat) speak() string { return'meow' }interface Speaker { speak() string }fn perform(s Speaker) { println(s.speak()) } dog := Dog{} cat := Cat{} perform(dog)// "woof" perform(cat)// "meow"
A type implements an interface by implementing its methods. There is no explicit declaration of intent, no "implements" keyword.
enum Color { red green blue } fn main() {mut color := Color.red// V knows that `color` is a `Color`. No need to use `color = Color.green` here. color = .green println(color)// "1" TODO: print "green"? if color == .green { println("it's green") } }
struct User { id int name string }struct Repo { users []User }fn new_repo() Repo { return Repo { users: [User{1, 'Andrew'}, User {2, 'Bob'}, User {10, 'Charles'}] } }fn (r Repo) find_user_by_id(id int) ?User { for user in r.users {if user.id == id {// V automatically wraps this into an option type return user } } return error('User $idnot found' ) } fn main() { repo := new_repo() user := repo.find_user_by_id(10) or {// Option types must be handled by `or` blocks return //`or` block must end with `return`, `break`, or `continue` } println(user.id) //"10" println(user.name) //"Charles" }
V combines Option
and Result
into one type, so you don't need to decide which one to use.
The amount of work required to "upgrade" a function to an optional function is minimal:
you have to add a ?
to the return type and return an error when something goes wrong.
If you don't need to return an error, you can simply return none
.
This is the primary way of handling errors in V. They are still values, like in Go, but the advantage is that errors can't be unhandled, and handling them is a lot less verbose.
err
is defined inside an or
block and is set to the string message passed
to the error()
function. err
is empty if none
was returned.
user := repo.find_user_by_id(7) or { println(err)// "User 7 not found" return }
You can also propagate errors:
resp := http.get(url)? println(resp.body)
http.get
returns ?http.Response
. It was called with
?
, so the error is propagated to the calling function
(which must return an optional) or in case of
main
leads to a panic.
Basically the code above is a shorter version of
resp := http.get(url) or { panic(err) } println(resp.body)
V does not have a way to force unwrap an optional (like Rust's unwrap()
or Swift's !
). You have to use or { panic(err) }
instead.
struct Repo<T> { db DB }fn new_repo<T>(db DB) Repo<T> { return Repo<T>{db: db} }// This is a generic function. V will generate it for every type it's used with. fn (r Repo<T>) find_by_id(id int) ?T { table_name := T.name// in this example getting the name of the type gives us the table name return r.db.query_one<T>('select * from $table_name where id = ?', id) } db := new_db() users_repo := new_repo<User>(db) posts_repo := new_repo<Post>(db) user := users_repo.find_by_id(1)? post := posts_repo.find_by_id(1)?
foo()
concurrently, just
call it with go foo()
. Right now, it launches the function in a new system
thread. Soon coroutines and the scheduler will be implemented.
import jsonstruct User { name string age int// Use the `skip` attribute to skip certain fields foo Foo[skip] // If the field name is different in JSON, it can be specified last_name string[json:lastName] } data :='{ "name": "Frodo", "lastName": "Baggins", "age": 25 }' user := json.decode(User, data)or { eprintln('Failed to decode json' ) return } println(user.name) println(user.last_name) println(user.age)
JSON is very popular nowadays, that's why JSON support is built in.
The first argument of the json.decode
function is the type to decode to.
The second argument is the JSON string.
V generates code for JSON encoding and decoding. No runtime reflection is used. This results in much better performance.
All test functions have to be placed in// hello.v fn hello() string { return'Hello world' }// hello_test.v fn test_hello() {assert hello() =='Hello world' }
*_test.v
files and begin with test_
.
To run the tests do v hello_test.v
. To test an entire module, do
v test mymodule
.
assert
keyword can be used outside of tests as well.
The strings don't escapefn draw_text(s string, x, y int) { ... }fn draw_scene() { ... draw_text('hello $name1' , 10, 10) draw_text('hello $name2' , 100, 10) draw_text(strings.repeat('X' , 10000), 10, 50) ... }
draw_text
, so they are cleaned up when
the function exits.
In fact, the first two calls won't result in any allocations at all. These two strings are small, V will use a preallocated buffer for them.
fn test() []int { number := 7 // stack variable user := User{} // struct allocated on stack numbers := [1, 2, 3] // array allocated on heap, will be freed as the function exits println(number) println(user) println(numbers) numbers2 := [4, 5, 6] // array that's being returned, won't be freed here return numbers2 }
fn read_log() { f := os.open('log.txt' )defer { f.close() } ...if !ok {// defer statement will be called here, the file will be closed return } ...// defer statement will be called here, the file will be closed }
V has a built-in ORM that supports Postgres, and will soon support MySQL and SQLite.
The benefits of V ORM:
struct Customer {// struct name has to be the same as the table name for now id int// an integer id must be the first field name string nr_orders int country string } db := pg.connect(db_name, db_user)// select count(*) from Customer nr_customers := db.select count from Customer println('number of all customers: $nr_customers')// V syntax can be used to build queries // db.select returns an array uk_customers := db.select from Customer where country == 'uk' && nr_orders > 0 println(uk_customers.len) for customer in uk_customers { println('$customer.id - $customer.name') }// by adding `limit 1` we tell V that there will be only one object customer := db.select from Customer where id == 1 limit 1 println('$customer.id - $customer.name')// insert a new customer new_customer := Customer{name: 'Bob', nr_orders: 10} db.insert(new_customer)
v fmt file.v
It's recommended to set up your editor, so that vfmt runs on every save.
Always run vfmt before pushing your code.
Documentation for each function/type/const must be placed right before the declaration:
// clearall clears all bits in the array fn clearall() { }
The comment must start with the name of the definition.
An overview of the module must be placed in the first comment right after the module's name.
To generate documentation, run v doc path/to/module
(TODO this is
temporarily disabled).
#flag -lsqlite3 #include "sqlite3.h" struct C.sqlite3 struct C.sqlite3_stmt fn C.sqlite3_column_int(stmt C.sqlite3_stmt, n int) int fn main() { path := 'users.db' db := &C.sqlite3{!} // a temporary hack meaning `sqlite3* db = 0` C.sqlite3_open(path.str, &db) query := 'select count(*) from users' stmt := &C.sqlite3_stmt{!} C.sqlite3_prepare_v2(db, query.str, - 1, &stmt, 0) C.sqlite3_step(stmt) nr_users := C.sqlite3_column_int(stmt, 0) C.sqlite3_finalize(stmt) println(nr_users) }
Add #flag
directives to the top of your V files
to provide C compilation flags like -l
for
linking, -I
for adding include files locations, -D
for setting compile time variables, etc.
You can use different flags for different targets. Right now, linux
,
darwin
, and windows
are supported.
For now you have to use one flag per line:
#flag linux -lsdl2 #flag linux -Ivig #flag linux -DCIMGUI_DEFINE_ENUMS_AND_STRUCTS=1 #flag linux -DIMGUI_DISABLE_OBSOLETE_FUNCTIONS=1 #flag linux -DIMGUI_IMPL_API=
C strings can be converted to V strings with
string(cstring)
or
string(cstring, len)
.
V uses voidptr
for C's void*
and
byteptr
for C's byte*
or char*
.
To cast voidptr
to V references use user := &User(user_void_ptr)
.
voidptr
can also be dereferenced to V structs by casting: user := User(user_void_ptr)
.
Check out socket.v for an example of calling C code from V: https://github.com/vlang/v/blob/master/vlib/net/socket.v
To debug issues with the C code, v -show_c_cmd .
is useful. It prints the
C command that is used to build the program.
Compile time$if windows { println('Windows') }$if linux { println('Linux') }$if mac { println('macOS') }$if debug { println('debugging') }
if
starts with a $
. Right now it can only be used to detect
an OS or a -debug
compilation option.
// TODO: not implemented yet fn decode<T>(data string) T { mut result := T{} for field in T.fields { if field.typ =='string' { result.$field = get_string(data, field.name) } else if field.typ =='int' { result.$field = get_int(data, field.name) } } return result }// generates to: fn decode_User(data string) User { mut result := User{} result.name = get_string(data, 'name') result.age = get_int(data, 'age') return result }
struct Vec { x int y int }fn (a Vec) str() string {return '{$a.x, $a.y}' }fn (a Vec) + (b Vec) Vec {return Vec { a.x + b.x, a.y + b.y } }fn (a Vec) - (b Vec) Vec {return Vec { a.x - b.x, a.y - b.y } }fn main() { a := Vec{2, 3} b := Vec{4, 5} println(a + b)// "{6, 8}" println(a - b)// "{-2, -2}" }
Operator overloading goes against V's philosophy of simplicity and predictability. But since scientific and graphical applications are among V's domains, operator overloading is very important to have in order to improve readability:
a.add(b).add(c.mul(d))
is a lot less readable than a + b + c * d
.
To improve safety and maintainability, operator overloading has several limitations:
- It's only possible to overload +, -, *, /
operators.
- Calling other functions inside operator functions is not allowed.
- Operator functions can't modify their arguments.
- Both arguments must have the same type (just like with all operators in V).
fn main() { a := 10 asm x64 { mov eax, [a] add eax, 10 mov [a], eax } }
V can translate your C/C++ code to human readable V code.
Let's create a simple program test.cpp
first:
#include <vector> #include <string> #include <iostream> int main() { std::vector<std::string> s; s.push_back("V is "); s.push_back("awesome"); std::cout << s.size() << std::endl; return 0; }Run
v translate test.cpp
and V will generate test.v
:
fn main { mut s := [] s << 'V is ' s << 'awesome' println(s.len) }
An online C/C++ to V translator is coming soon.
When should you translate C code and when should you simply call C code from V?
If you have well-written, well-tested C code, then of course you can always simply call this C code from V.
Translating it to V gives you several advantages:
- If you plan to develop that code base, you now have everything in one language, which is much safer and easier to develop in than C.
- Cross-compilation becomes a lot easier. You don't have to worry about it at all.
- No more build flags and include files either.
module main import time import os [live] fn print_message() { println('Hello! Modify this message while the program is running.') } fn main() { for { print_message() time.sleep_ms(500) } }Build this example with
v -live message.v
.
Functions that you want to be reloaded must have [live]
attribute
before their definition.
Right now it's not possible to modify types while the program is running.
More examples, including a graphical application: github.com/vlang/v/tree/master/examples/hot_code_reloading.
v -os windows .or
v -os linux .(Cross compiling for macOS is temporarily not possible.)
If you don't have any C dependencies, that's all you need to do. This works even
when compiling GUI apps using the ui
module or graphical apps using
gg
.
You will need to install Clang, LLD linker, and download a zip file with libraries and include files for Windows and Linux. V will provide you with a link.
V can be used as an alternative to Bash to write deployment scripts, build scripts, etc.
The advantage of using V for this is the simplicity and predictability of the language, and cross-platform support. "V scripts" run on Unix-like systems as well as on Windows.
Use .vsh file extension. It will make all functions in the os
module global (so that you can use ls()
instead of os.ls()
, for example).
rm(Now you can either compile this like a normal V program and get an executable you can deploy and run anywhere:'build/*' )// Same as: for filein ls('build/' ) { rm(file) } mv('*.v' ,'build/' )// Same as: for filein ls('.' ) {if file.ends_with('.v' ) { mv(file,'build/' ) } }
v deploy.v && ./deploy
Or just run it more like a traditional bash script:
v run deploy.v
break const continue defer else enum fn for go goto if import in interface match module mut none or pub return struct type
+ sum integers, floats, strings - difference integers, floats * product integers, floats / quotient integers, floats % remainder integers & bitwise AND integers | bitwise OR integers ^ bitwise XOR integers << left shift integer << unsigned integer >> right shift integer >> unsigned integer Precedence Operator 5 * / % << >> & 4 + - | ^ 3 == != < <= > >= 2 && 1 || Assignment Operators += -= *= /= %= &= |= ^= >>= <<=


VISHESH FITNESS
HOME
REGISTER
GALLERY
FITNESS CALCULATOR
CONTACT US
JOIN THE BEST GYM IN THE WORLD
NAME:
AGE:
GENDER:
PHONE NUMBER:
LOCALITY:
SUBMIT


| Team name | Sport | Stadium |
|---|---|---|
| Chicago Blackhawks | Hockey | United Center |
| Chicago Bulls | Basketball | United Center |
| Chicago Bears | Football | Soldier Field |
| Chicago Cubs | Baseball | Wrigley Field |
| Chicago White Sox | Baseball | US Cellular Field |
| North America | Asia | Europe |
|---|---|---|
| Canada | Thailand | Belgium |
| Mexico | Turkey | |
| United States of America |
China | Poland |
| Japan | France |


vagrant up
, Issues down
platform as code for the research and learning environment
Austin Parker | @austinlparker for UAlbany Open Source Festival 2014
Setting the Stage
Imagine this scenario
- Large, multidisciplinary research project or learning environment
- Participants and colleagues scattered across non-geographically contiguous areas
- Non-standard configurations of computing resources
The Problem
How do we make sure everyone is working with the same tools?
The Solution
Infrastructure as Code
What is Infrastructure as Code?
What about tools, though?
A virtual server is nice and all, but we need more for our purposes
Introducing Platform As Code
- Extend the IaC model to include development tools and libraries
- Less support headaches, quickly onboard new contributors or learners
- Customize to your specific needs - target specific versions and lock
- Write Once, Run Anywhere - deploy locally or in the cloud
The Foundations of PaC
- vagrant
- Manage and provision virtualized development environments
- Simple configuration, easy to share files between host and client OS
- puppet
- Flexible and customizable automation framework
- Declarative, model-based approach to define the desired state of an environment
Getting Started
Download Vagrant at http://www.vagrantup.com/downloads.html
Find a Vagrantbox at https://vagrantcloud.com/discover/featured
Initial Setup
mkdir vagrant
cd vagrant
vagrant box add hashicorp/precise32
vagrant init
mkdir vagrant/manifests
touch vagrant/manifests/default.pp
Final Notes
- Performance may be an issue, but you can deploy to the cloud
- VMWare user? You're in luck.
- Puppet and Vagrant are much deeper than what we've seen today
Questions?
Note: You can find the sample files used in this presentation at my github


| aws_services |
| ARN |
Principal |
Account Owner |
External ID |
| arn:aws:iam::123456789012:role/service-role/AWSCloud9SSMAccessRole |
[cloud9.amazonaws.com, ec2.amazonaws.com] |
-
|
|
| arn:aws:iam::123456789012:role/service-role/AWSDeepRacerAccessRole |
[deepracer.amazonaws.com] |
-
|
|
|
| org_accounts |
| ARN |
Principal |
Account Owner |
External ID |
| arn:aws:iam::123456789012:role/AWS-QuickSetup-StackSet-Local-ExecutionRole |
[arn:aws:iam::00000000003:role/AWS-QuickSetup-StackSet-Local-AdministrationRole] |
Example Org Account - CREATED
ACTIVE |
|
| arn:aws:iam::123456789012:role/AWSCloudFormationStackSetExecutionRole |
[arn:aws:iam::00000000002:root] |
Example Org Billing Account - INVITED
ACTIVE |
|
|
| unknown_accounts |
| ARN |
Principal |
Account Owner |
External ID |
| arn:aws:iam::123456789012:role/Notintheregister |
['arn:aws:iam:666666666777:root'] |
-
|
True |
| arn:aws:iam::123456789012:role/TotallyLegitRole |
['arn:aws:iam:666666666666:root'] |
-
|
False |
|
| known_accounts |
| ARN |
Principal |
Account Owner |
External ID |
| arn:aws:iam::123456789012:role/Crowdstrike |
[arn:aws:iam::292230061137:root] |
Crowdstrike Falcon - https://www.crowdstrike.com/falcon/2020/wp-content/uploads/2020/10/Crowdstrike-AWS-ControlTower-Implementation-Guide.pdf |
True |
|


Happy Children’s Day: Check out 20 cutest pictures of B-town star kids
by Kajol MathurIt’s Children’s Day today and just the thought of it brings a big smile on all of ours faces. These toddlers have their own sweet ways to brighten up our days which further makes it more fun celebrating the special occasion. Everything from their innocence to their cute naughtiness – there’s nothing you cannot adore about them. Right from getting candid around the paparazzi to posing with their parents, these munchkins always leave us gushing.
Be it Taimur Ali Khan’s play dates with Karan Johar’s twins – Yash and Roohi to Misha Kapoor bonding with Zain Kapoor – we have it all for you. On this special day today, we have picked the cutest pictures of B-town star kids who manage to rule our feeds almost each day. Check out their 20 adorable pictures here.
Enjoy…
Taimur Ali Khan
Kiaan Raj Kapoor, Taimur Ali Khan, Roohi Johar
Taimur Ali Khan, Inaaya Naumi Kemmu
Inaaya Naumi Kemmu
Inaaya Naumi Kemmu, Taimur Ali Khan
Roohi Johar, Yash Johar
Roohi Johar, Yash Johar
Yash Johar, Taimur Ali Khan
Yash Johar, Roohi Johar
Misha Kapoor
Mira Kapoor, Zain Kapoor
Zain Kapoor
Misha Kapoor, Mira Kapoor
Misha Kapoor
Nitara Kumar
Shah Rukh Khan, AbRam Khan
Shah Rukh Khan, AbRam Khan
Nitara Kumar, Akshay Kumar
Radhya Takhtani, Esha Deol
Laksshya Kapoor


BOROFAIR- acetic acid solution/ drops
Major Pharmaceuticals
Acetic Acid 2% in Aqueous Aluminum Acetate Otic Solution contains acetic acid 2% as the active ingredient, in a solution containing aluminum acetate (formed from Aluminum Sulfate, Calcium Carbonate, Glacial Acetic Acid), Boric Acid, Sodium Hydroxide and Purified Water. Sodium Hydroxide and/or Glacial Acetic Acid may be added to adjust the pH (3.5 to 5.0). Acetic Acid 2% in Aqueous Aluminum Acetate Otic Solution is instilled in the external auditory canal. Acetic acid is an astringent and antimicrobial agent.
Chemically, acetic acid is C2H4O2 and has the following structural formula:
Molecular weight: 60.05
Acetic acid is antibacterial and antifungal and is effective against microorganisms (bacteria and fungi) that infect the ears of patients with acute diffuse external otitis. In vitro tests, minimum lethal-time was less than 0.25 minutes when bacteria and fungi isolated from patients with otitis externa were exposed to 2% acetic acid. Quantitative absorption of acetic acid 2% from external auditory canal is not known.
For the treatment of superficial infections of the external auditory canal caused by organisms susceptible to the action of the antimicrobial.
Hypersensitivity to acetic acid or any of the ingredients in this product. Perforated tympanic membranes is considered a contraindication to the use of any external ear canal medication.
Avoid use or use with caution in patients with perforated tympanic membrane (See CONTRAINDICATIONS).
No Toxic effect has been reported with overdosage of Acetic Acid 2% in Aqueous Aluminum Acetate Otic Solution.
The patient should lie on the side with the affected ear uppermost. Instill 4 to 6 drops into the external auditory canal and maintain this position for 5 minutes. Repeat the procedure every 2 to 3 hours.
Acetic Acid 2% in Aqueous Aluminum Acetate Otic Solution is available in 60 mL plastic squeeze bottle with otic tip
Prod. No. 06620.
Store between 15˚ - 30˚ C (59˚ - 86˚ F).
PROTECT FROM FREEZING
DO NOT USE IF IMPRINTED NECKBAND IS NOT INTACT.
KEEP OUT OF REACH OF CHILDREN.
|
BOROFAIR
acetic acid in aqueous aluminum acetate solution/ drops | ||||||||||||||||||||
| ||||||||||||||||||||
| ||||||||||||||||||||
| ||||||||||||||||||||
|
| Labeler - Major Pharmaceuticals (191427277) |


| I l@ve RuBoard |
Extending and Embedding the Python Interpreter, by Guido van Rossum is included in HTML format with every Python distribution. Just click Help on the PythonWin toolbar.
O'Reilly's Programming Python and IDG's Internet Programming with Python, by Watters, van Rossum and Ahlstrom, both contain sections on extending and embedding. The former is far more detailed while the latter is ideal starting point for beginning C programmers.
SWIG lives at http://www.swig.org/ and has good manuals available for download.
PyDelphi is available from http://www.multimania.com/marat/. You can also find it, along with this book's examples, at http://starship.python.net/crew/mhammond/ppw32/.
CallDLL and WinDLL are available in the DynWin package from http://www.nightmare.com. The key files are included with the examples at http://starship.python.net/crew/mhammond/ppw32/.
| I l@ve RuBoard |


Here we replicate the simple example from German Rodriguez’s “Simple Script” example:
Let us read the fuel efficiency data that is shipped with Stata
. sysuse auto, clear (1978 Automobile Data)
To study how fuel efficiency depends on weight it is useful to transform the dependent variable from “miles per gallon” to “gallons per 100 miles”
. gen gphm = 100/mpg
We then obtain a more linear relationship
. twoway scatter gphm weight || lfit gphm weight /// > , ytitle(Gallons per Mile) legend(off) . graph export auto.png, width(500) replace (file auto.png written in PNG format)
That’s all for now!


Saha reveals why Van Nistelrooy once made Cristiano Ronaldo cry
Louis Saha has spoken about the time Ruud van Nistelrooy made Cristiano Ronaldo in a Manchester United training session.
Van Nistelrooy scored a remarkable 150 goals for the Red Devils in 219 appearances for the club before leaving for Real Madrid back in 2006.
There were rumours that Saha’s appearance in the League Cup final ahead of Van Nistelrooy was the final straw as the Dutchman left United for LaLiga, but the former France international says the pair had a good relationship.
Saha told FourFourTwo: “He was always really nice with me; he maybe had a problem with the choice made by the manager, but never with me. He was obsessed about goals, and I respect that.
“I know some people said I maybe pushed him to a move away from the club, but that’s totally b*******. He was such a good player – he just had an issue with the manager – and I was maybe good enough for the manager to replace him, but I could have played with him, too.”
And in the same interview in the new issue of FourFourTwo, Saha also has claimed that Van Nistelrooy made Ronaldo cry in training at United.
“Ruud had that kind of ego: he wanted all the passes,” Saha added. “And sometimes, for the development of Cristiano Ronaldo and Wayne Rooney, it was difficult for the manager to deal with.
“Did Ruud make Ronaldo cry? Yeah, there were stories because I think they ended up in an argument at the moment when Cristiano’s father had passed away, so it wasn’t the right moment. Things like that happen when two players have lots of spirit, but I’m sure Ruud regrets some of his words.
“Cristiano was just an animal. I don’t know if you can say that he was a human! You could see from when he was 18 or 19 that this guy was not normal.
“These players who have all the ability recognise that it’s also about working harder than anyone – not just talent. The top seeds in tennis don’t hit the ball better or have better technique; no, they work harder than anyone, and Cristiano did that.”


THE BLACK HISTORY IPSUM
IPSUM Home
THE TEAM
THE SOURCES
Find Links to Author Pages
Ta-Nehasi Coates
Fredrick Douglass
W.E.B. Du Bois
Marcus Garvey
Bell Hooks
M.L.K. Jr
Abe Lincoln
Malcolm X
Barak Obama
Sojourner Truth
Booker T. Washington
Ida Wells
Cornel West


HW4, practice with Git¶
This assignment (one long question) reviews materials in lectures 6 and 7.
In all cases, programming should be done in python 3 and you should use any good programming practices that we have discussed so far (e.g. use of white space).
1. Git¶
i. After Wolfman initialized the repo planets
from the empty directory, Dracula wants to start tracking information about moons.¶
Despite Wolfman’s concerns, Dracula creates a moons
project inside
his planets
project with the following sequence of commands:
$ cd ~/Desktop # return to Desktop directory
$ cd planets # go into planets directory, which is already a Git repository
$ ls -a # ensure the .git sub-directory is still present in the planets directory
$ mkdir moons # make a sub-directory planets/moons
$ cd moons # go into moons sub-directory
$ git init # make the moons sub-directory a Git repository
$ ls -a # ensure the .git sub-directory is present indicating we have created a new Git repository
Is the git init
command, run inside the moons
sub-directory,
required for tracking files stored in the moons
sub-directory?
ii. Choosing a Commit Message¶
Which of the following commit messages would be most appropriate for the
commits made to mars.txt
in class?
- “Changes”
- “Added line ‘But the Mummy will appreciate the lack of humidity’ to mars.txt”
- “Discuss effects of Mars’ climate on the Mummy”
iii.  Committing Multiple Files¶
The staging area can hold changes from any number of files that you want to commit as a single snapshot.
- Add some text to
mars.txt
noting your decision to consider Venus as a base - Create a new file
venus.txt
with your initial thoughts about Venus as a base for you and your friends - Add changes from both files to the staging area, and commit those changes.
v. Creating a new repository¶
- Create a new Git repository on your computer called
bio
. - Write a three-line biography for yourself in a file called
me.txt
, commit your changes - Modify one line, add a fourth line
- Display the differences between its updated state and its original state.
vi. Recovering Older Versions of a File¶
Pilar has made changes to the Python script that she has been working on for weeks, and the modifications she made this morning “broke” the script and it no longer runs. She has spent ~ 1hr trying to fix it, with no luck…
Luckily, she has been keeping track of her project’s versions using Git!
Which commands below will let her recover the last committed version of
her Python script called data_cruncher.py
?
vii. Reverting a Commit¶
Pilar is collaborating on her Python script with her colleagues and
realizes her last commit to the group repository is wrong and wants to
undo it. Jennifer needs to undo correctly so everyone in the group
repository gets the correct change. git revert [wrong commit ID]
will make a new commit that undoes Jennifer’s previous wrong commit.
Therefore git revert
is different than git checkout [commit ID]
because checkout
is for local changes not committed to the group
repository. Below are the right steps and explanations for Jennifer to
use git revert
, what is the missing command?
________ # Look at the git history of the project to find the commit ID
- Copy the ID (the first few characters of the ID, e.g. 0g1d055).
git revert [commit ID]
- Type in the new commit message.
- Save and close
viii. Understanding Workflow and History¶
What is the output of the last command in
$ cd planets
$ echo "Venus is beautiful and full of love" > venus.txt
$ git add venus.txt
$ echo "Venus is too hot to be suitable as a base" >> venus.txt
$ git commit -m "Comment on Venus as an unsuitable base"
$ git checkout HEAD venus.txt
$ cat venus.txt #this will print the contents of venus.txt to the screen
ix. Getting Rid of Staged Changes¶
git checkout
can be used to restore a previous commit when unstaged
changes have been made, but will it also work for changes that have been
staged but not committed? Make a change to mars.txt
, add that
change, and use git checkout
to see if you can remove your change.
x. What does the following command do?¶
$ git log --patch HEAD~3 *.txt
xi. Ignoring Nested Files¶
Given a directory structure that looks like:
results/data
results/plots
How would you ignore only results/plots
and not results/data
?
xii. Including Specific Files¶
How would you ignore all .data
files in your root directory except
for final.data
? Hint: Find out what !
(the exclamation point
operator) does
xiii. Ignoring all data Files in a Directory¶
Given a directory structure that looks like:
results/data/position/gps/a.data
results/data/position/gps/b.data
results/data/position/gps/c.data
results/data/position/gps/info.txt
results/plots
What’s the shortest .gitignore
rule you could write to ignore all
.data
files in result/data/position/gps
? Do not ignore the
info.txt
.
xiv. The Order of Rules¶
Given a .gitignore
file with the following contents: ~~.data
!.data~~
What will be the result?
xv. Log Files¶
You wrote a script that creates many intermediate log-files of the form
log_01
, log_02
, log_03
, etc. You want to keep them but you
do not want to track them through git
.
- Write one
.gitignore
entry that excludes files of the formlog_01
,log_02
, etc. - Test your “ignore pattern” by creating some dummy files of the form
log_01
, etc. - You find that the file
log_01
is very important after all, add it to the tracked files without changing the.gitignore
again. - What other types of files could reside in your directory that you do
not want to track and thus would exclude via
.gitignore
?
xvi. GitHub GUI¶
Browse to your planets
repository on GitHub. Under the Code tab,
find and click on the text that says “XX commits” (where “XX” is some
number). Hover over, and click on, the three buttons to the right of
each commit. What information can you gather/explore from these buttons?
How would you get that same information in the shell?
xvii. GitHub Timestamp¶
Create a remote repository on GitHub. Push the contents of your local repository to the remote. Make changes to your local repository and push these changes. Go to the repo you just created on GitHub and check the timestamps of the files. How does GitHub record times, and why?
xviii. Push vs. Commit¶
How is “git push” different from “git commit”?
ixx. Fixing Remote Settings¶
It happens quite often in practice that you made a typo in the remote URL. This exercise is about how to fix this kind of issue. First start by adding a remote with an invalid URL:
git remote add broken https://github.com/this/url/is/invalid
Do you get an error when adding a remote? Can you think of a command
that would make it obvious that your remote URL was not valid? Can you
figure out how to fix the URL (tip: use git remote -h
)? Don’t forget
to clean up and remove this remote once you are done with this exercise.
xx. GitHub License and README files¶
We learned about creating a remote repository on GitHub, but when you initialized your GitHub repo, you didn’t add a README.md or a license file. If you had, what do you think would have happened when you tried to link your local and remote repositories?
xxi. Review Changes¶
The Owner pushed commits to the repository without giving any information to the Collaborator. How can the Collaborator find out what has changed with command line? And on GitHub?
xxii. Conflicts on Non-textual files¶
What does Git do when there is a conflict in an image or some other non-textual file that is stored in version control?
xxiii. A Typical Work Session¶
You sit down at your computer to work on a shared project that is tracked in a remote Git repository. During your work session, you take the following actions, but not in this order:
- Make changes by appending the number
100
to a text filenumbers.txt
- Update remote repository to match the local repository.
- After your pull request is accepted, Celebrate your success.
- Request a pull from your working branch to the master branch.
- Update local repository to match the remote repository.
- Stage changes to be committed.
- Merge the master branch into your working branch to check for any conflicts.
- Commit changes to the local repository.
- Make a new branch where you will make all your changes, and switch to it.
In what order should you perform these actions to minimize the chances of conflicts? Put the commands above in order in the action column of the table below. When you have the order right, see if you can write the corresponding commands in the command column. A few steps are populated to get you started.
| order | action … … . | command … … … … … … . |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 | ||
| 4 | ||
| 5 | ||
| 6 | ||
| 7 | ||
| 8 | ||
| 9 | Celebrate! | echo “Cheers!” |


I wonder if this will work now?
Who knows but welcome to class!
Testing to see if the changes get pushed to git and website